Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

To mock an object, does it have to be either implementing an interface or marked virtual?

Tags:

moq

or can the class be implementing an abstract class also?

like image 914
mrblah Avatar asked Dec 29 '09 03:12

mrblah


People also ask

Can you mock without an interface?

The commercial edition allows you to mock concrete objects without having to change anything in their interface. This is an elevated feature.

Can you mock an interface?

We can use org. mockito. Mockito class mock() method to create a mock object of a given class or interface. This is really the simplest way to mock an object.

Can I mock non virtual methods C#?

Moq cannot mock non virtual methods on classes. Either use other mocking frameworks such as Type mock Isolator which actually weaves IL into your assembly or place an interface on EmailService and mock that.

How does a mock object work?

A object that you want to test may have dependencies on other complex objects. To isolate the behavior of the object you want to test you replace the other objects by mocks that simulate the behavior of the real objects. So in simple words, mocking is creating objects that simulate the behavior of real objects.


2 Answers

To mock a type, it must either be an interface (this is also called being pure virtual) or have virtual members (abstract members are also virtual).

By this definition, you can mock everything which is virtual.

Essentially, dynamic mocks don't do anything you couldn't do by hand.

Let's say you are programming against an interface such as this one:

public interface IMyInterface
{
    string Foo(string s);
}

You could manually create a test-specific implementation of IMyInterface that ignores the input parameter and always returns the same output:

public class MyClass : IMyInterface
{
    public string Foo(string s)
    {
        return "Bar";
    }
}

However, that becomes repetitive really fast if you want to test how the consumer responds to different return values, so instead of coding up your Test Doubles by hand, you can have a framework dynamically create them for you.

Imagine that dynamic mocks really write code similar to the MyClass implementation above (they don't actually write the code, they dynamically emit the types, but it's an accurate enough analogy).

Here's how you could define the same behavior as MyClass with Moq:

var mock = new Mock<IMyInterface>();
mock.Setup(x => x.Foo(It.IsAny<string>())).Returns("Bar");

In both cases, the construcor of the created class will be called when the object is created. As an interface has no constructor, this will normally be the default constructor (of MyClass and the dynamically emitted class, respectively).

You can do the same with concrete types such as this one:

public class MyBase
{
    public virtual string Ploeh()
    {
        return "Fnaah";
    }
}

By hand, you would be able to derive from MyBase and override the Ploeh method because it's virtual:

public class TestSpecificChild : MyBase
{
    public override string Ploeh()
    {
        return "Ndøh";
    }
}

A dynamic mock library can do the same, and the same is true for abstract methods.

However, you can't write code that overrides a non-virtual or internal member, and neither can dynamic mocks. They can only do what you can do by hand.

Caveat: The above description is true for most dynamic mocks with the exception of TypeMock, which is different and... scary.

like image 173
Mark Seemann Avatar answered Sep 21 '22 21:09

Mark Seemann


From Stephen Walther's blog:

You can use Moq to create mocks from both interfaces and existing classes. There are some requirements on the classes. The class can’t be sealed. Furthermore, the method being mocked must be marked as virtual. You cannot mock static methods (use the adaptor pattern to mock a static method).

like image 23
duffymo Avatar answered Sep 22 '22 21:09

duffymo