2

別の日、別の質問。私のサービスレイヤーには次のメソッドがあります

public MatchViewData CreateMatch(string user)
{
    var matchViewData = !HasReachedMaxNumberOfMatchesLimit(user) ?
        CreateMatchAndAddToRepository(user) : 
        MatchViewData.NewInstance(new Match(user));

    matchViewData.LimitReached = HasReachedMaxNumberOfMatchesLimit(user);
    return matchViewData;
}

このメソッドは、このヘルパー メソッドを呼び出して、新しい一致オブジェクトを作成します。

private MatchViewData CreateMatchAndAddToRepository(string user)
{
    var match = new Match(user);
    MatchRepository.Add(match);
    return MatchViewData.NewInstance(match);
}

リポジトリは指定された一致オブジェクトを保存し、ID を 0 より大きい値に設定します。

public void Add(Match match)
{
    Check.Require(match != null);
    var numberOfMatchesBefore = Matches.Count;
    SetIdPerReflection(match, NextVal());
    Matches.Add(match);
    Check.Ensure(numberOfMatchesBefore == Matches.Count - 1);
}

matchviewdata オブジェクトは、一致オブジェクトの一部のプロパティ (id を含む) をコピーします。

単体テストでは、サービス内の結果のビューデータ オブジェクトの ID が 0 より大きいことを確認する必要があります。これをアーカイブするには、リポジトリと add メソッドの動作をモックする必要があります。ただし、サービス メソッドは呼び出されるたびに新しい一致オブジェクトを作成し、リポジトリの add メソッドは参照された一致オブジェクトを更新します (戻り値は必要ありません)。これをmoqで解決する方法がわかりません。

これはこれまでの私の単体テストです:

[Test]
public void ServiceCreateMatchReturnedMatchViewDataHasNonZeroId()
{
    var match = TestUtils.FakePersistentMatch(User, 1);
    var repositoryMock = new Mock<IMatchRepository>();
    repositoryMock.Setup(
           r => r.Add(It.IsAny<Match>())).Callback(() => match.Id = 1);
    var serviceFacade = new DefaultServiceFacade(repositoryMock.Object);

    var returnedMatch = serviceFacade.CreateMatch(User);

    Assert.That(returnedMatch.Id, Is.GreaterThan(0));
}

他のバリエーションをいくつか試しましたが、何も機能しません。

4

1 に答える 1

3

あなたの問題はこの行にあるようです。

repositoryMock.Setup(
       r => r.Add(It.IsAny<Match>())).Callback(() => match.Id = 1);

ここで実際に行っているのは、サービスで作成された新しい一致ではなく、テストで宣言した最初の一致オブジェクトの ID を設定することです。

リポジトリに提供するMatchオブジェクトは内部で作成されるため、Test メソッドでそれを参照してコールバックを設定する簡単な方法が思い浮かびません。私にとって、これは、1 つの単体テストで多くのテストをしようとしている可能性がある兆候です。

Add メソッドが呼び出されることを単純にテストし、別のテストを記述して、期待どおりに動作することを確認する必要があると思います。

私はこのようなことを提案します;

[Test]
public void ServiceAddsNewMatchToRepository()
{
   var repositoryMock = new Mock<IMatchRepository>();
   bool addCalled = false;
   repositoryMock
       .Expect(r => r.Add(It.Is<Match>(x => x.Id == 0))
       .Callback(() => addCalled = true);

   var serviceFacade = new DefaultServiceFacade(repositoryMock.Object);
   serviceFacade.CreateMatch(User);

   Assert.True(addCalled);
}

....

[Test]
public void AddingANewMatchGeneratesANewId()
{
  var match = new Match(user);
  var matchRepository = new MatchRepository();
  var returnedMatch = matchRepository.Add(match);

  Assert.That(returnedMatch.Id, Is.GreaterThan(0));      
}
于 2009-04-18T17:13:29.827 に答える