Tuesday, December 9, 2014

Using Overridden members with Partial Mocks for abstract Types

For a serious unit testing mocking framework is a required piece. It allows creating mocks for dependencies we don't want to instantiate in our code. We discussed about partial mocks long time ago [refer post]. They are specially useful for testing abstract types. Actually they provide a proxy implementation for the virtual / abstract members.

In this post we are going to discuss a special case when we have overridden some members of a parent type. We might not have overridden the other members or we just are good with the default null proxy implementation. Generally the mocking framework would just provide proxy implementation for all virtual / abstract members. How can we make sure that it uses the implementation in our type if we have provided so.

For our demo project, we are using nunit with Moq. Let's create a test project, and add the following nuget packages.

Here we have introduced BaseClass with a public member [Calculate] and two abstract members [CalculateCore and SomeOtherMethod]. It is inherited from another type ChildClass, which provides an implementation of CalculateCore only.

Now let us try to add unit tests for testing the functionality for this type. Here we have added a methods to check the result of Calculate method. Since we have added a definition of CalculateCore member, it should be adding the two parameters and just returns the result.

When we run this test, we get failure. If we look at the result, it doesn't actually make a lot of sense. Actually it is not even using the CalculateCore implementation from ChildClass.

But can we actually tell mocking framework to avoid providing implementation of overridden members. Actually Moq supports this by providing CallBase member for Mock. Here we have another implementation of the same ChildClass. The only difference is that mock has this member set. Now it should use the overridden member, CalculateCore, and test should pass.

And test passes now, Zindabad!!!

No comments: