测试单个接口的不同具体实现?

时间:2016-02-11 17:21:40

标签: c# unit-testing testing mocking tdd

我有以下代码:

public interface IFoo
{
    IResult ResolveTheProblem(IBar inputData);
}

public class FastFoo : IFoo
{
    public IResult ResolveTheProblem(IBar inputData)
    {
        // Algorithm A - resolves the problem really fast
    }
}

public class SlowFoo : IFoo
{
    public IResult ResolveTheProblem(IBar inputData)
    {
        // Algorithm B - different algoritm, resolves the problem slow
    }
}

要测试的最重要的是每个算法的实现。 为了测试,我使用NUnit和NSubstitute。现在我有这样的测试:

    [Test]
    public void FooTest()
    {
        IFoo foo = Substitute.For<IFoo>();
        IBar bar = Substitute.For<IBar>();

        IResult result = foo.ResolveTheProblem(bar);

        Assert.IsNotNull(result);
    }

我的两个问题:

  • 这个测试甚至是必要的吗?我不确定
  • 如何测试每个IFoo(FastFoo和SlowFoo)的实现?

编辑:FastFoo和SlowFoo是两个完全不同的实现。两者的结果是从1到10的随机数。

2 个答案:

答案 0 :(得分:3)

不,没有必要。为什么要测试替代实现? 您可以替换您的依赖项,例如IBar。 您测试具体实现:

[Test]    
public void SlowFooTest()
{    
    IBar bar = Substitute.For<IBar>();
    // Setup bar expectations / canned responses as required
    var foo = new SlowFoo(bar);
    IResult result = foo.ResolveTheProblem(bar);
    // Validate result from concrete class:
    Assert.IsNotNull(result);
}

[Test]    
public void FastFooTest()
{    
    IBar bar = Substitute.For<IBar>();
    var foo = new FastFoo(bar);
    IResult result = foo.ResolveTheProblem(bar);
    Assert.IsNotNull(result);
}

答案 1 :(得分:1)

  

该测试是否必要?我不确定

该测试似乎没有做任何事情。您似乎正在为正在测试的服务创建测试双重。

  

如何测试每个IFoo(FastFoo和SlowFoo)的实现?

对于FastFoo和SlowFoo,答案总是一样的,或者FastFoo对速度的交易准确度是否相同?

如果它们总是相同的继承。使用摘要FooTest创建基础CreateFoo。然后是两个具体的实现。

如果它们不总是相同,那么再次继承但是带有模糊元素。

abstract class AbstractFooTester {
    [Test]
    public void WhenBarIsSomethingThenResultIsSomethingElse() {
         var mockRandomNumberGenerator = createRandomNumberMock(5);
         var mockBar = Substitute.For<IBar>();
         // set up Bar
         ...
        var subject = createFoo(mockRandomNumberGenerator);
        IResult result = subject.ResolveTheProblem(bar);

        AssertResult(result, ...);
    }
    abstract Foo createFoo(RandomNumberGenertor g);
    RandomNumberGenertor createRandomNumberMock(Int i) { ... }
}

class TestFastFoo extends AbstractFooTester {
      Foo createFoo(RandomNumberGenertor g) { return new FastFoo(g); }
}

class TestSlowFoo extends AbstractFooTester {
      Foo createFoo(RandomNumberGenertor g) { return new SlowFoo(g); }
}