Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking a base class method call with Moq

Tags:

I am modifiying a class method which formats some input paramater dates which are subsequently used as params in a method call into the base class (which lives in another assembly).

I want to verify that the dates i pass in to my method are in the correct format when they are passed to the base class method so i would like to Moq the base class method call. Is this possible with Moq?

like image 823
user158363 Avatar asked Aug 18 '09 10:08

user158363


People also ask

How to mock base class method using Moq?

This means that you must ask Moq to give you a Mock<B> . However, this means that the emitted type derives from B, and while it can override MyMethod (which is still virtual) and call its base (B. MyMethod), it has no way of getting to the original class and verify that B calls base.

Can you mock a class with Moq?

You can use Moq to create mock objects that simulate or mimic a real object. Moq can be used to mock both classes and interfaces. However, there are a few limitations you should be aware of. The classes to be mocked can't be static or sealed, and the method being mocked should be marked as virtual.

How does Moq mock work?

Mock objects allow you to mimic the behavior of classes and interfaces, letting the code in the test interact with them as if they were real. This isolates the code you're testing, ensuring that it works on its own and that no other code will make the tests fail.


2 Answers

As of 2013 with latest Moq you can. Here is an example

public class ViewModelBase {     public virtual bool IsValid(DateTime date)     {         //some complex shared stuff here     } }   public class MyViewModel : ViewModelBase {     public void Save(DateTime date)     {         if (IsValid(date))         {             //do something here         }     } }  public void MyTest() {     //arrange     var mockMyViewModel = new Mock<MyViewModel>(){CallBase = true};     mockMyViewModel.Setup(x => x.IsValid(It.IsAny<DateTime>())).Returns(true);      //act     mockMyViewModel.Object.Save();      //assert     //do your assertions here }  
like image 172
JimSan Avatar answered Oct 14 '22 17:10

JimSan


If I understand your question correctly, you have a class A defined in some other assembly, and then an class B implemented more or less like this:

public class B : A {     public override MyMethod(object input)     {         // Do something         base.MyMethod(input);     } } 

And now you want to verify that base.MyMethod is called?

I don't see how you can do this with a dynamic mock library. All dynamic mock libraries (with the exception of TypeMock) work by dynamically emitting classes that derive from the type in question.

In your case, you can't very well ask Moq to derive from A, since you want to test B.

This means that you must ask Moq to give you a Mock<B>. However, this means that the emitted type derives from B, and while it can override MyMethod (which is still virtual) and call its base (B.MyMethod), it has no way of getting to the original class and verify that B calls base.MyMethod.

Imagine that you have to write a class (C) that derives from B. While you can override MyMethod, there's no way you can verify that B calls A:

public class C : B {     public override MyMethod(object input)     {         // How to verify that base calls its base?         // base in this context means B, not A     } } 

Again with the possible exception of TypeMock, dynamic mock libraries cannot do anything that you cannot do manually.

However, I would assume that calling the base method you are trying to verify has some observable side effect, so if possible, can you use state-based testing instead of behaviour-based testing to verify the outcome of calling the method?

In any case, state-based testing ought to be your default approach in most cases.

like image 32
Mark Seemann Avatar answered Oct 14 '22 16:10

Mark Seemann