This is the third post in my unit testing series. So far we have created a single EpiDependencies class to manage Episervers API in a single class. This will make out constructors a lot cleaner, as we only need to pas 1 thing in, rather than 8 or 9 things.
In the second post, we created some basic unit tests using Moq to mock up these dependencies to make previously un-testable code testable.
In this post, I'm going to talk about Fakes. If you have never heard about a fake then the concept is very easy... it's a class that implements an interface you want to test. The questions I get asked a lot is why use fakes at all, why not use Mocks, or, when should I use which method?
In general, I recommend mocking as opposed to fakes. Mocking allows for cleaner and easier to maintain code. The reason for using the main reason I would use a fake is if something has a protected or abstract method making it unmockable, take this example:
If you run this bit of code (from the example code provided at the end of this post) Moq will throw an exception:
This means that because the ContentRepository is not virtual, it cannot be mocked. In this example, as we are using EpiDependencies, which is a class we have created, it's not such a big deal, however, you can't do this in every circumstance. If you try to unit test Episerver Commerce for example you will hit this issue a lot.
In our example, EpiDependencies inherits from IEpiDependencies. What we can now do is create a FakeEpiDependencies object that inherits from IEpiDependencies and makes the ContentRepository repository virtual, allowing us to Mock the function we want to.
We now have our fake object that we can pass into anywhere that expects IEpiDependencies; this method is now virtual meaning if we now tried the code that failed above and replace the object to mock from EpiDependencies to FakeDependencies, our code will now run!
This might seem quite trivial but it's a massive help in getting full test coverage in your application. In many of Episervers API's (commerce is a much worse offender) you might want to test a function like adding a billing address to a customer and you can't change the underlining API code to make it testable.
If it uses an interface, you can create a Fake object, override setters or even write custom code within the Fake to allow you to create more in-depth tests that dig deeper into your application. At the end of this process my unit test then looked like this:
Another good example of using a Fake is to cut down on the amount of code in your test projects. Take our Dependencies class. If you need to pass epi dependencies into all your view models, blocks, controllers, fixtures etc.. writing the same code over to mock it up is a waste.
One way to get around this would be to create a base class which set the mocks up for you and an alternative and simpler approach would be to create a FakeDepencies class and then use Mock within the properties that retrieve the dependencies. Using this approach means you write less code as the set-up code is all stored within one place:
If you end up creating an Epi Commerce dependencies handler, which has a lot of API's and dependencies, that file will end up being quite large and this trick will save you time having to mock the whole thing up each time :)
The code for the whole of this series can be found from my Github profile, here enjoy