Я пытаюсь выполнить модульное тестирование метода, который выполняет довольно сложную операцию, но я смог разбить эту операцию на несколько шагов на поддельных интерфейсах, например:
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 подэтапа). Это все-в-одном, поэтому попытка использовать несколько небольших тестов не сработает. Он начинает приближаться к коду только для записи для будущих сопровождающих, включая меня в следующем месяце, когда я забыл, как он работает. Там должен быть лучший путь! Верно?