standards-c-sharp

Prefer black box over white box testing

Consider the following code:

public interface IDataProvider
{
    string GetData();
}
 
public class Sleepy
{
    private readonly IDataProvider _dataProvider;

    public Sleepy(IDataProvider dataProvider)
    {
        _dataProvider = dataProvider;
    }

    public string GetSleepyData()
    {
        return _dataProvider.GetData() + " zzzzzzz";
    }
}

Don’t

Notice the call to dataProviderMock.Verify().

[Test]
public void GetSleepyData_MakesSleepy()
{
    var dataProviderMock = new Mock<IDataProvider>();
    dataProviderMock.Setup(x => x.GetData()).Returns("I'm tired");
    var sleepy = new Sleepy(dataProviderMock.Object);

    var result = sleepy.GetSleepyData();
    
    Assert.AreEqual("I'm tired zzzzzzz", result);
    dataProviderMock.Verify(x => x.GetData(), Times.Once);
}

Do

For this case there is no need to verify the call to the data provider was made. This is an implementation detail that might change in the future, and could therefore cause the test to fail. All we care is that the output is correct for the given input - ie. the zeds were appended. We don’t care how this was achieved.

[Test]
public void GetSleepyData_MakesSleepy()
{
    var dataProviderMock = new Mock<IDataProvider>();
    dataProviderMock.Setup(x => x.GetData()).Returns("I'm tired");
    var sleepy = new Sleepy(dataProviderMock.Object);

    var result = sleepy.GetSleepyData();
     
    Assert.AreEqual("I'm tired zzzzzzz", result);
}