Unit testing 如何使用犀牛模拟流?
我正在做文件转换,这是一个多步骤的过程。STEAP1的输出作为输入传递到步骤2。步骤2的输出是分配回Context.FinalOutput属性的最终输出。因为最终的输出是Stream,所以我希望调用者决定使用哪个流。这就是调用者将流作为上下文的一部分传递的原因。 我只是想知道,我用Rhino Mocks编写的测试是否正确Unit testing 如何使用犀牛模拟流?,unit-testing,rhino-mocks,Unit Testing,Rhino Mocks,我正在做文件转换,这是一个多步骤的过程。STEAP1的输出作为输入传递到步骤2。步骤2的输出是分配回Context.FinalOutput属性的最终输出。因为最终的输出是Stream,所以我希望调用者决定使用哪个流。这就是调用者将流作为上下文的一部分传递的原因。 我只是想知道,我用Rhino Mocks编写的测试是否正确 namespace Test { public interface IContextInfo { // Input parameters her
namespace Test
{
public interface IContextInfo
{
// Input parameters here
// Output parameter
Stream FinalOutput { get; set; }
}
public interface IStep1
{
void DoStep1(IContextInfo contextInfo, Stream outputOfStep1);
}
public interface IStep2
{
void DoStep2(Stream outputOfStep1, Stream outputOfStep2);
}
public interface IController
{
void Execute();
}
public class MyController : IController
{
IContextInfo _contextInfo = null;
IStep1 _step1 = null;
IStep2 _step2 = null;
public MyController(IContextInfo contextInfo, IStep1 step1, IStep2 step2)
{
_contextInfo = contextInfo;
_step1 = step1;
_step2 = step2;
}
public void Execute()
{
using (Stream outputOfStep1 = new MemoryStream())
{
this._step1.DoStep1(_contextInfo, outputOfStep1);
this._step2.DoStep2(outputOfStep1, this._contextInfo.FinalOutput);
}
}
}
[TestClass]
public class ControllerTests
{
[TestMethod]
public void Controller_Execute()
{
MockRepository mock = new MockRepository();
var context = mock.Stub<IContextInfo>();
var step1 = mock.Stub<IStep1>();
var step2 = mock.Stub<IStep2>();
var outputOfStep1 = mock.StrictMock<Stream>();
context.FinalOutput = mock.StrictMock<Stream>();
step1.Expect(x => x.DoStep1(context, outputOfStep1)).IgnoreArguments();
step2.Expect(c => c.DoStep2(outputOfStep1,context.FinalOutput)).IgnoreArguments();
mock.ReplayAll();
var controller = new MyController(context, step1, step2);
controller.Execute();
//Assert
Assert.IsNotNull(controller);
mock.VerifyAll();
}
}
}
根据测试的组成方式,测试的目的似乎是验证在Execute方法中是否正确调用了两个依赖项_step1和_step2类。这是编写的第一个很好的测试 不幸的是,您的测试没有正确地测试该条件。由于您正在为_step1和_step2设置期望值,因此需要将它们从存根更改为模拟 此外,由于您没有对输出设置期望值,所以应该将它们从模拟中更改为存根,或者完全删除它们,因为您正在调用IgnoreArguments 为了清晰起见,我做了一些额外的修改: 我重命名了您的方法以更恰当地描述测试。我通常遵循以下模式:MethodUnderTest\u Condition\u ExpectedResult。我还删除了Assert.IsNotNullcontroller;因为它不特别适用于正在测试的条件
当然,您可能需要针对该方法编写更多的测试,例如,确保步骤1的输出是步骤2的输入。最重要的是,记住在测试中要清楚地知道你到底在测试什么,并尽最大努力一次测试一个条件。你想测试什么?你有编译错误吗?运行测试时出错?
[TestMethod]
public void Execute_IsCalled_Step1AndStep2AreCalled()
{
//Arrange
MockRepository mock = new MockRepository();
var context = mock.Stub<IContextInfo>();
var step1 = mock.StrictMock<IStep1>();
var step2 = mock.StrictMock<IStep2>();
step1.Expect(x => x.DoStep1(null, null)).IgnoreArguments();
step2.Expect(c => c.DoStep2(null, null)).IgnoreArguments();
mock.ReplayAll();
//Act
var controller = new MyController(context, step1, step2);
controller.Execute();
//Assert
mock.VerifyAll();
}