Don't Let Your Test Doubles Fool You

During unit testing it is common to substitute dependencies with a test double (see Martin Fowler's disambiguation). This is necessary for isolating the tested environment and consequently also the potential source of error in case of a test failure. Thus also the name unit testing.

Let's assume the very simple example of an AnimalFactory which, given the name of an animal and some type, creates an according object representation. When coding a unit test for some object which is dependent on the AnimalFactory, you'd most probably exchange that factory with a stub which returns exactly the object you need in your test case. A possible setup of Moq could look as follows.

//Setup
var mockAnimalFactory = new Mock<IAnimalFactory>();
mockAnimalFactory.Setup(x => x.CreateAnimal(It.IsAny<string>(), It.IsAny<AnimalType>())
.Returns(new Dog{
Name = "SomeName"
});
So far, so good. Now assume your code makes different calls to the IAnimalFactory.CreateAnimal(...) in your code (which during testing is substituted with your test double) and it also makes use of object reference comparison for some reason. This may lead to quite strange side-effects, mainly because the mockAnimalFactory will always return the same instance of the Dog object. I don't know if you knew this.

The solution is actually pretty simple. Mock.Returns(...) has different overloads, one of which takes a function for creating the actual return object. This has the consequence that the function is evaluated on every call to the stub's CreateAnimal(...) method, thus returning different object instances each time.
var mockAnimalFactory = new Mock<IAnimalFactory>();
mockAnimalFactory.Setup(x => x.CreateAnimal(It.IsAny<string>(), It.IsAny<AnimalType>())
.Returns(() => new Dog{
Name = "SomeName"
});
Kindle

Comments

0

Your ad here?