Runar Ovesen Hjerpbakk

Science-based software development

Moq: Mock a method from an interface

tl;dr

If you have a class using a method from one or more interfaces, you can use Moq to fake the behavior of the methods from the interface. Your code can still work with the class directly.

What is Moq

Moq is a powerful mocking library for C#.

Moq is designed to be a very practical, unobtrusive and straight-forward way to quickly setup dependencies for your tests.

It is very useful for faking implementations of interfaces so that you don't need to litter your tests with implementations that you don't need.

Example

The code below shows a class, MyClass, which calls a method on a complex object internally. We do not want to test the ComplexClass class here, only the behavior of the MyClass implementation.

How to test the behavior of MyClass's Verify method? Use Moq to setup the implementation.

public class MyClass {
	private readonly ComplexClass complexClass;
	
	public MyClass(ComplexClass complexClass) {
		this.complexClass = complexClass;
	}
	
	public void Verify() {
		((IVerifiable)complexClass).Verify();
	}
	
	// Imagine many more uninteresting methods...  
	public void Uninteresting1() {
	}
}

public class ComplexClass : IVerifiable {
	public object NeededProperty { get; set; }
	
	// Verifies the state of the object
	public void Verify() {
		if(NeededProperty == null) {
			// Don't use this exception message in production :)
			throw new InvalidOperationException("Method is invalid for the current state of the object");
		}
	}
	
	// Imagine many more uninteresting methods...  
	public void Uninteresting2() {
	}
}

public interface IVerifiable {
	void Verify();
}

[TestClass]
public class MyClassTests {
	[TestMethod]
	public void Verify_ComplexObjectIsValid_ShouldNotThrowException() {
		var complexClass = new ComplexClass();
		var myClass = new MyClass(complexClass);
		
		myClass.Verify();
		
		// Test fails with exception :( Must be replaced with a working test.
	}
	
	[TestMethod]
	public void Verify_ComplexObjectIsValid_ShouldReallyNotThrowException() {
		var complexClassFake = new Mock<ComplexClass>();
		var verifiable = complexClassFake.As<IVerifiable>();
		verifiable.Setup(v => v.Verify()).Verifiable();
		var myClass = new MyClass(complexClassFake.Object);
		
		myClass.Verify();
		
		verifiable.Verify();
		// Test works as expected :)
	}
}

The Verify_ComplexObjectIsValid_ShouldNotThrowException test method fails because the complexClassobject has not been set up with the needed dependencies.

In the Verify_ComplexObjectIsValid_ShouldReallyNotThrowException test method, Moq fakes the behavior of the ComplexClass.Verify method and sets up an expectation that this method should be called. Now we just verify that no exception is being thrown and that this method is called.

The behavior of MyClass was successfully tested without need of coupling the test with ComplexClass's internal logic.