Omar
Omar

Reputation: 40182

Should I assert that a dependency's method is called in every unit test for a given method?

Give this class:

public class ClassToTest
{
    private IService _service;

    public ClassToTest(IService service)
    {
        _service = service;
    }   

    public Output MethodToTest(string input)
    {
        if (string.IsNullOrEmpty(input))
            throw new ArgumentNullException("input");

        var output = new Output();

        if (input == "Yes")
            output.Value = "X";
        else
            output.Value = "Y";

        _service.AnotherMethod(input);
        return output;
    }
}

Should I assert that _service.AnotherMethod(input) is called in every unit test for this method as I do below or just test it in one method?

// Test #1
[Test]
public void ThrowsExceptionForEmptyInput()
{
    // Arrange
    var service = new Mock<IService>();
    var classToTest = new ClassToTest(service.Object);

    // Act
    var result = () => classToTest.MethodToTest("");

    // Assert
    result.ShouldThrow<ArgumentNullException>();
}



// Test #2
[Test]
public void ReturnsXForYesAndCallsAnotherMethod()
{
    // Arrange
    string input = "Yes";
    var service = new Mock<IService>();
    var classToTest = new ClassToTest(service.Object);

    // Act
    var result = classToTest.MethodToTest(input);

    // Assert
    Assert.Equals("X", result.Value);
    service.Verify(m => m.AnotherMethod(input), Times.Once());
}

// Test #3
[Test]
public void ReturnsYForAnyValueAndCallsAnotherMethod()
{
    // Arrange
    string input = "Other Value Not Yes";
    var service = new Mock<IService>();
    var classToTest = new ClassToTest(service.Object);

    // Act
    var result = classToTest.MethodToTest(input);

    // Assert
    Assert.Equals("X", result.Value);
    service.Verify(m => m.AnotherMethod(input), Times.Once());
}

Upvotes: 2

Views: 138

Answers (1)

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236238

I suggest you assert _service.AnotherMethod(input) only once. That will make only one test fail if the service is not called and you will know the source of the problem. Otherwise you will have a bunch of failed tests, and you will have to search for the source of failure.

In a perfect world, you should have many tests with single assertions giving you only one reason to fail for each test.

Upvotes: 5

Related Questions