BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Testing
.NET 1.1+

Using Stubs

The twelfth part of the Automated Unit Testing tutorial discusses the use of stubs. Stubs are used to simplify the testing of code that relies upon other classes, helping a unit of code to be isolated from its dependencies.

Creating the Stubs

The next step is to create stubs for the oxygen safety calculator and the ammonia meter. There are various ways in which you can create your stubs. Some developers like to have a separate stub for each set of canned responses. Others like to have configurable stubs that can be reused. Both options have their benefits so we will use each in the example.

For the IO2SafetyCalculator implementation we will create two stubs. One will be used to indicate that the oxygen level is safe and one that it is not. The classes will be named accordingly. The code for the two stubs is shown below. This should be added to the project containing the tests, as we do not want the stubs to be compiled into the final application.

public class SafeO2SafetyCalculatorStub : IO2SafetyCalculator
{
    public bool OxygenLevelIsSafe()
    {
        return true;
    }
}

public class UnsafeO2SafetyCalculatorStub : IO2SafetyCalculator
{
    public bool OxygenLevelIsSafe()
    {
        return false;
    }
}

To stub the ammonia meter we'll use a single class that can return a configurable result. Although the IAmmoniaMeter interface only defines the get accessor for the PartsPerMillion property, we'll add the set accessor too so that the return value can be specified during the Arrange part of the tests.

public class AmmoniaMeterStub : IAmmoniaMeter
{
    int _ppm;

    public int PartsPerMillion
    {
        get { return _ppm; }
        set { _ppm = value; }
    }
}

Using the Stubs in Tests

With the stubs created we can add the unit tests for the WaterQualityReporter class. The first test's code is shown below. Here we start by creating an instance of the SafeO2SafetyCalculatorStub class, which will return a result indicating that the oxygen saturation of the water is good. Next we create an AmmoniaMeterStub object and set its PartsPerMillion property to zero, which is a safe value. The Arrange part of the test is completed by creating the WaterQualityReporter and injecting the two stubs as dependencies via the constructor.

To complete the test we execute the CheckWater method and assert that the result is correct.

[Test]
public void GoodWaterQualityReturnsCorrectMessage()
{
    IO2SafetyCalculator o2 = new SafeO2SafetyCalculatorStub();
    AmmoniaMeterStub ammonia = new AmmoniaMeterStub();
    ammonia.PartsPerMillion = 0;
    WaterQualityReporter reporter = new WaterQualityReporter(o2, ammonia);

    Assert.AreEqual("Oxygen: OK, Ammonia: OK", reporter.CheckWater());
}

The stubs that we have created have given us full control over the dependencies that the WaterQualityReporter class utilises. We can now complete the test fixture using various configurations of the stubs in order to test all paths through the CheckWater method:

[Test]
public void UnsafeOxygenReturnsCorrectMessage()
{
    IO2SafetyCalculator o2 = new UnsafeO2SafetyCalculatorStub();
    AmmoniaMeterStub ammonia = new AmmoniaMeterStub();
    ammonia.PartsPerMillion = 0;
    WaterQualityReporter reporter = new WaterQualityReporter(o2, ammonia);

    Assert.AreEqual("Oxygen: Low, Ammonia: OK", reporter.CheckWater());
}

[Test]
public void UnsafeAmmoniaReturnsCorrectMessage()
{
    IO2SafetyCalculator o2 = new SafeO2SafetyCalculatorStub();
    AmmoniaMeterStub ammonia = new AmmoniaMeterStub();
    ammonia.PartsPerMillion = 1;
    WaterQualityReporter reporter = new WaterQualityReporter(o2, ammonia);

    Assert.AreEqual("Oxygen: OK, Ammonia: High", reporter.CheckWater());
}

[Test]
public void UnsafeAmmoniaAndOxygenReturnsCorrectMessage()
{
    IO2SafetyCalculator o2 = new UnsafeO2SafetyCalculatorStub();
    AmmoniaMeterStub ammonia = new AmmoniaMeterStub();
    ammonia.PartsPerMillion = 1;
    WaterQualityReporter reporter = new WaterQualityReporter(o2, ammonia);

    Assert.AreEqual("Oxygen: Low, Ammonia: High", reporter.CheckWater());
}
28 April 2011