Home Mocking a class dependency which casts into a derived type using Moq
Post
Cancel

Mocking a class dependency which casts into a derived type using Moq

Let's say we have the following, one class named Implementor which has an IParentInterface dependency.

In method DoWork ofthe class, we call the interface's method, but we also call another method, which comes bycasting the dependency to a derived interface.
All, good, we goahead and create a unit test project, adding the Moq package as well, in order to mock dependencies.

Code is as follows:

Implementor.cs

public class Implementor
    {
        private readonly IParentInterface _parent;

        public Implementor(IParentInterface parent)
        {
            _parent = parent;
        }

        public void DoWork()
        {
            // Do work with parent interface method
            _parent.ParentWork();

            // Do work with child interface method
            ((IChildInterface)_parent).ChildWork();
        }
    }

IParentInterface.cs

Now, both interfacesare simple, they all have a void method without any incoming parameters.

public interface IParentInterface
    {
        void ParentWork();
    }

IChildInterface.cs

This interface innherits from IParentInterface, but it has its own contract as well.

public interface IChildInterface: IParentInterface
    {
        void ChildWork();
    }

That poses a problem, because we want to make some unit tests that mock the dependency and verify the call to the underlying methods.How are we going to test this? If we don'tmockboth we are going to receive an error, whichis going to break our tests.

Solution

Solution to this problem is the .As<T>() method of the Moq library. You can find more in the Github Wiki.
Method .As<T> is used to implement multiple interfaces into a single mock.

Our setup in the TestFixture (I am using NUnit as testing framework in the example, but you are free to use any of your choice) is like this:

private Mock<IParentInterface> _parentMock;

        [SetUp]
        public void Setup()
        {
            _parentMock = new Mock<IParentInterface>();
        }

I just create a mockinstance of the IParentInterface, the one that I am going to inject into the class.
Let's see this in action in an actual test, I am going to test the DoWork() method and verify that ParentWork() as well as ChildWork() are called once:

[Test]
        public void DoWork_VerifyParentWorkAndChildWorkCalls_Test()
        {
            // Arrange
            _parentMock.Setup(m => m.ParentWork()).Verifiable();
            _parentMock.As<IChildInterface>().Setup(m => m.ChildWork()).Verifiable();
            var implementor = new Implementor(_parentMock.Object);

            // Act
            implementor.DoWork();

            // Assert
            _parentMock.Verify(m => m.ParentWork(), Times.Once());
            _parentMock.As<IChildInterface>().Verify(m => m.ChildWork(), Times.Once());
        }

The unit test method follows the AAA pattern,as you can see by the comments, in order to maintain a clean visual representation of the unit test.
In the actual implementation now, first I setup the ParentWork() method and mark it as Verifiable, which means that when I call the Verify method on that mock object, I will be able to tellif that was called or not.
In order to test the derived interface method, I used the .As<IChildInterface>, which essentially is implementing the IChildInterface into the _parentMock object. I mark this as verifiable, then I instantiate theImplementor, passing the _parentMock object.
In the Assert part, I verify that these methods were actually called. In order to check that the ChildWork was called, I need to implement the IChildInterface to the mock object again, calling the Verify method next.

Summary

Ifyour mock object can cast tosomething else, like aderived interface, and you need to test this implementation within your Act, the .As<T>() method of Moq library is your friend.
Code from this post can be found in this Github repository.

 

This post is licensed under CC BY 4.0 by the author.

AngularJS with Typescript and SystemJS

Using OWIN to self-host Web API and secure endpoints

Comments powered by Disqus.