Moq - How to unit test changes to a link in a method

Another day, another question. My service level has the following method

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

The method calls this helper method to create a new matching object:

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

The specified correspondence object is stored in the repository and id is set to some value> 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); } 

The matchviewdata object copies some properties of the match object (including the identifier).

My unit test must make sure that the resulting viewdata object in the service has an identifier> 0. To archive this, I have to make fun of the repository and behavior of the add method. But the service method creates a new correspondence object each time it was called, and the add method in the repository updates the associated correspondence object (no return value is needed). I have no idea to solve this with moq.

This is my unit test so far:

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

I tried some other options - nothing works.

+2
source share
1 answer

It seems to me that your problem is in this line;

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

What you are actually doing here is to set the identifier of the first match object that you announced in your test, and not the new match created in your service.

Since the Match object that you will be delivering to the repository is created internally, I cannot think of an easy way to refer to it in the test method to set up a callback for it. For me, this is a sign that you can experience too much in one unit test.

I think you just need to verify that the Add method is called and write a separate test to make sure that it works as exepected.

I suggest something like this:

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

All Articles