Unit Testing: Mocking Base Class Methods With Moq

0 Flares Twitter 0 Facebook 0 StumbleUpon 0 Google+ 0 LinkedIn 0 0 Flares ×

Yesterday I had to give someone a hand with a bit of unit testing where we had a fairly complex base class where we really wanted to mock out some of the base class methods. I used a solution which I had used before but it took me a while to remember the syntax so I thought I’d do a short post about it – the flag is in Moq mock object, and is called CallBase, but it does require you to rework your tests a little bit.

A Simple Example

This example is pretty similar to the situation I encountered yesterday, with all the noise taken out.

Lets say I have a base class called ViewModelBase, with a method that does some complex validation:

And a derived type with a method Save like this:

When I’m testing the method “Save”, I probably don’t want to have to test everything inside of “IsValid” – it may even be code from a 3rd party which I definitely don’t want to test. This is where I can use CallBase to my advantage.

Mocking Out Base Class Methods With Moq

The key to using CallBase in this way is to actually mock out the class your are testing, set CallBase to be true on the mock, and then stub out the call to the base class method – but an example says this better:

So what’s happening?

Well we’re creating a mocked version of our target class, but setting the call base property to true – this instructs moq to execute any calls made on the mock, on the actual object itself – i.e. if we call “Save” on the mocked object, our save method will get called.

Next we stub out the call to IsValid – in this case moq will call our stubbed out version of IsValid, rather than the base class implementation.

Then we call our save method on the target object and do our assertions and verifications.

Finally

One thing to note though is that this will only work for virtual or abstract base class methods, and that if you have constructor arguments on your target class you will need to pass those arguments to Moq – but thats for another day.

,

  • Flynn

    This test code doesn’t even compile. And if it did, it would not test anything!

    • Matt

      Hi Flynn,

      What problems are you having with getting the code to compile?

      The code doesn’t test anything because its a sample – its meant to represent how you can mock out a base class method call, so that you can focus on testing just your class. If it would help I could provide a more complete example with some actual code and assertions?

      Matt

  • Williams

    I think the issue is line 5 in MyTest I get an error as well saying you cannot access protected constructor Mock here. If I can change it to var mockMyViewModel = new Mock(){CallBase = true};

    Then everything compiles for me at least

    • Matt

      There must have been some issue when I moved from blogger to here which had removed some of the formatting around line 5 of the last code sample.

      I’ve corrected it now.

      Thanks for the feedback

      Matt

  • Praveen Angyan

    Hey Matt, long time user of Moq here. Recently I’ve run into a use case that is almost, but not fully covered by your code. Let’s say that I want to verify that IsValid is called when Save is called on the object. How do I do this. In my own code I have set up a verification on IsValid, but this never seems to be called and the verification fails in my unit test. Any ideas on how to do this?

    I basically don’t care about what IsValid does since this is covered in other unit tests. What I do want to assert is that IsValid is called when the object is saved.

    • Hey Praveen,

      You should be able to just verify it using:

      mockMyViewModel.Verify(x => x.IsValid(), Times.Once());

      I just gave it a quick go and it seemed to work okay

      • Praveen Angyan

        I see the problem. I actually prefer mocking on interfaces. This works well since I usually inject my dependencies (as interfaces) into other classes in my system.

        However, in order to be able to use CallBase for what I need it for, I needed to mock out the class that implements the interface and use virtual on both methods.

  • Abhinav Singh

    if i am not using {CallBase = true} then also my test case is passing.i am not able to understand use.Using latest Moq.Please help here

The Essential App Marketing Kit
Subscribe To My Newsletter To Get an Entire Chapter From The Book for FREE
Never display this again
0 Flares Twitter 0 Facebook 0 StumbleUpon 0 Google+ 0 LinkedIn 0 0 Flares ×