So let’s just dive in today. Our current test class is fairly clean and straightforward, but we’re not using all of Moq’s capabilities yet. One notable thing is that we have to remember to call VerifyAll on all of our individual mocks. Fortunately, Moq provides us with a tool to mitigate this problem: MockRepository is a class we can use to create and track mocks, and verify all expectations at once.
In the real world, Factories manufacture items for output. In software engineering, Factories create object instances for us so we can avoid using the “new” operator. Factories also give us substantially more control when testing, and can even provide a means of verifying “Black box” operations.
Why would we want to avoid the “new” operator? Isn’t that what it’s there for?
Well, yes, but newing up a dependency within a class goes against the concept of dependency injection. Thinking back to our ReallyHardToTest class, we know we’re creating a new instance of SomeModel in the constructor, and one of our methods provides a way to change the SomeModel instance. The problem is that since we create the instance within ReallyHardToTest, we cannot control it or even verify that an instance is created. Furthermore, we can’t verify that the SetFilename method actually does what it says on the tin because the SomeModel instance isn’t exposed publicly by that class.
Factories Help Us Build Things
At its root, the factory pattern (there are actually a few variants) encapsulates the logic for creating instances of particular types. When employing these patterns, now dependent classes can have a factory injected, and then ask the factory for a new instance when they need it. Since the factory is injected, we can control it at test time – we even get to control the instance returned by the factory!
In advanced scenarios, for example when a factory will be invoked repeatedly, we can use advanced features of Moq, including SetupSequence() to return different instances in a specific order.
Programming to Abstractions is a another common architectural pattern that facilitates unit testing. Abstractions provide a way for us to decouple specific implementation details from the consuming class. Another benefit of abstractions is that we can substitute alternate implementations if needed – something that is very difficult to do otherwise.
Let’s start by looking at our trusty ReallyHardToTest class that we’ve been working with:
Let’s focus on the ReallyHardToTest constructor, which takes an instance of SomeOtherDependency. We know from prior tutorials that we can’t mock concrete types, but we want to make sure that the ReallyHardToTest constructor invokes SomeOtherDependency.DoSomething(). So how can we make this more testable?