开发者

How to use Rhino Mocks for Stream?

开发者 https://www.devze.com 2023-04-02 17:06 出处:网络
I\'m doing file conversion which is mutiple steps process. The output of STEAP1 is passed as the input to STEP2. The output of STEP2 is the final output which assigned back to Context.FinalOutput prop

I'm doing file conversion which is mutiple steps process. The output of STEAP1 is passed as the input to STEP2. The output of STEP2 is the final output which assigned back to Context.FinalOutput property. Since the Final Output is Stream, i want the caller to decide which stream to use. Thats why caller will pass the Stream as a part of the context. I just wanted to know, the test i have written using Rhino Mocks is correct?

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 (Str开发者_如何学JAVAeam 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();
        }
    }
}


Based on how your test is composed, it appears as if the intent of your test is to verify that the classes two dependencies _step1 and _step2 are called correctly in the Execute() method. This is a good first test to write.

Unfortunately, your test does not properly test that condition. Since you are setting expectations on _step1 and _step2, you need to change them from stubs to mocks.

Additionally, since you are not setting expectations on your output, you should change them to stubs from mocks or remove them entirely, because you are calling IgnoreArguments()

[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();
}

I have made a couple of additional changes for clarity:

I renamed your method to more appropriately describe the test. I usually follow the pattern: MethodUnderTest_Condition_ExpectedResult(). Also I removed Assert.IsNotNull(controller); as it does not apply specifically to the condition that is being tested.

There are certainly more tests you may want to write against this method (Ensuring the output of Step1 is the input of Step2, for example). Most importantly, remember to be clear in your test about what exactly you are testing, and do your best to test one condition at a time.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号