代码之家  ›  专栏  ›  技术社区  ›  Michael Wallasch

Moq-如何对方法中的引用进行单元测试更改

  •  2
  • Michael Wallasch  · 技术社区  · 17 年前

    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);
    }
    

    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);
    }
    

    这是我到目前为止的单元测试:

    [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));
    }
    

    我尝试了其他一些变体,但都没用。

    1 回复  |  直到 17 年前
        1
  •  3
  •   Kirschstein    17 年前

    在我看来,你的问题就在这方面;

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

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

    因为 Match 您将提供给存储库的对象是在内部创建的,我想不出一种简单的方法在您的测试方法中引用它来为其设置回调。对我来说,这表明您可能试图在一个单元测试中测试太多。

    我认为您应该简单地测试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));      
    }
    
    推荐文章