2009-04-17 58 views
2

另一天,另一个问题。我的服务层具有以下方法Moq - 如何在一个方法中的单位测试参考变化

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)的一些属性。

我的单元测试应该验证服务生成的viewdata对象的id> 0。为了实现这一点,我必须模拟存储库和add方法的行为。但是service方法每次调用它时会创建一个新的匹配对象,并且存储库上的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)); 
} 

我尝试了一些其他的变化 - 没有什么作品。

回答

3

它在我看来你的问题是在这一行;

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

你实际上这里做的是设置您已在测试中声明的第一个匹配对象的ID,而不是新的比赛在你的服务中创建。

由于Match将提供给Repository的对象是在内部创建的,所以我想不出一个简单的方法在Test方法中引用它来设置它的回调。对我而言,这是一个你可能试图在单元测试中过多测试的迹象。

我认为你应该简单地测试一下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));  
} 
+0

哦,亲爱的。你是对的: - )(我已经有了第二个测试)。但有时你没有看到树木...感谢 – 2009-04-21 13:42:17