我试图单元测试执行一个相当复杂的操作的方法,但我已经能够向下打破运行到了一些关于mockable接口的步骤如下所示:如何避免大型多步骤单元测试?
public class Foo
{
public Foo(IDependency1 dp1, IDependency2 dp2, IDependency3 dp3, IDependency4 dp4)
{
...
}
public IEnumerable<int> Frobnicate(IInput input)
{
var step1 = _dependency1.DoSomeWork(input);
var step2 = _dependency2.DoAdditionalWork(step1);
var step3 = _dependency3.DoEvenMoreWork(step2);
return _dependency4.DoFinalWork(step3);
}
private IDependency1 _dependency1;
private IDependency2 _dependency2;
private IDependency3 _dependency3;
private IDependency4 _dependency4;
}
我使用一个模拟框架(Rhino.Mocks)来生成用于测试目的的模拟,并且以这里所示的方式构建代码迄今为止非常有效。但是,如何在不需要每次都需要每个模拟对象和每个期望值的大型测试的情况下对这种方法进行单元测试?例如:
[Test]
public void FrobnicateDoesSomeWorkAndAdditionalWorkAndEvenMoreWorkAndFinalWorkAndReturnsResult()
{
var fakeInput = ...;
var step1 = ...;
var step2 = ...;
var step3 = ...;
var fakeOutput = ...;
MockRepository mocks = new MockRepository();
var mockDependency1 = mocks.CreateMock<IDependency1>();
Expect.Call(mockDependency1.DoSomeWork(fakeInput)).Return(step1);
var mockDependency2 = mocks.CreateMock<IDependency2>();
Expect.Call(mockDependency2.DoAdditionalWork(step1)).Return(step2);
var mockDependency3 = mocks.CreateMock<IDependency3>();
Expect.Call(mockDependency3.DoEvenMoreWork(step2)).Return(step3);
var mockDependency4 = mocks.CreateMock<IDependency4>();
Expect.Call(mockDependency4.DoFinalWork(step3)).Return(fakeOutput);
mocks.ReplayAll();
Foo foo = new Foo(mockDependency1, mockDependency2, mockDependency3, mockDependency4);
Assert.AreSame(fakeOutput, foo.Frobnicate(fakeInput));
mocks.VerifyAll();
}
这似乎令人难以置信的脆弱。对Frobnicate实施的任何更改都会导致此测试失败(如将步骤3分解为2个子步骤)。这是一种一体化的方式,所以尝试使用多个较小的测试是行不通的。它开始为未来的维护人员提供只写代码,下个月我已经忘记了它是如何工作的。一定有更好的方法!对?
该示例似乎只测试一个存根? – 2009-02-26 20:19:53