Use MockBehaviour.Strict
when you create your mockSiteRepository
and mockAddressRepository
.
When you run your test, you should see an exception that says your invocation of IAddressRepository.Edit(Site) failed with MockBehaviour.Strict
. Now you know exactly what methods are being called on your repository, so you will know that it has indeed edited the site.
Then you have to make the tests pass. Setup the mock repositories in your test to expect the edit. You don't know exactly which instance of Site
or Address
is going to be passed to your mock repository so you have to use the It.Is<T> method to allow any matching instance. Something like
mockSiteRepository.Setup(repo => repo.Save(It.Is<Site>(s => s.SiteID == testForm.SiteID)));
that way you verify that what's being passed to the repository at least has the right ID.
Another way to approach this, that I find a bit more robust, is to use the It.IsAny<T> method, assign the site to a local variable in the test method, and then Assert about it afterwards. I find this leads to more self-explanatory error messages and easier debugging. For instance:
//arrange
var mockSiteRepository = new Mock<ISiteRepository>();
var testForm = new Site { SiteID = 0 };
Site savedSite = null;
mockSiteRepository
.Setup(repo => repo.Save(It.IsAny<Site>()))
.Callback<Site>(s => savedSite = s);
//act
var controller = new SiteController(mockChemical.Object, mockSiteRepository.Object, mockChemicalRelationRepository.Object, mockAddressRepository.Object);
var result = controller.Edit(testForm);
//assert
Assert.That(savedSite, Is.Not.Null); //this verifies that your setup was called
Assert.That(savedSite.SiteID, Is.EqualTo(testForm.SiteID));
Assert.That(savedSite.Name, Is.EqualTo(testForm.Name));
//do your other asserts
//always VerifyAll at the end so you know your setups were all called
mockSiteRepository.VerifyAll();