Monday, 21 March 2011

Using Moq to verify that a method does NOT get called

I recently had a bit of a brain fade when using Moq. I wanted to check that one method on a mocked class wasn’t called but that another was. Imagine a class like this:

public class Testable
{
    IService _service;
    
    public Testable(IService service)
    {
        _service = service;
    }

    public void MethodToTest(int i)
    {
        if(i <= 0)
        {
            _service.DoSomething();
            return;
        }
        
        _service.DoSomethingElse();
    }
}

I want to test that when if i > 0 only the _service.DoSomethingElse() method is called. I need the mock implementation of IService to throw an exception if the wrong method is called. The solution is to ask Moq to create a strict mock:

using Moq;
using NUnit.Framework;

[TestFixture]
public class TestableTest 
{
    [Test]
    public void MethodToTest_WhenArgumentGreaterThanZero_DoesSomethingElse()
    {
        // Arrange
        Mock<IService> mockService = new Mock<IService>(MockBehavior.Strict);
        mockService.SetUp(x => x.DoSomethingElse());
        
        Testable testable = new Testable(mockService.Object);
        
        // Act
        testable.MethodToTest(1);
        
        // Assert
        mockService.Verify(x => x.DoSomethingElse());
    }
}

When MockBehavior.Strict is used, Moq will throw an exception if any method is called that does not have a corresponding setup. In this case if the DoesSomething() method is called and exception will be thrown and the test will fail.