Как использовать Rhino Mocks для Stream? - PullRequest
0 голосов
/ 06 сентября 2011

Я делаю преобразование файла, которое состоит из нескольких шагов. Выход STEAP1 передается в качестве входа в STEP2. Вывод STEP2 является окончательным выводом, который присваивается обратно свойству Context.FinalOutput. Поскольку конечный результат - поток, я хочу, чтобы вызывающая сторона решала, какой поток использовать. Вот почему вызывающая сторона будет передавать поток как часть контекста. Я просто хотел знать, правильный ли тест, который я написал с помощью Rhino Mocks?

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

1 Ответ

0 голосов
/ 07 сентября 2011

В зависимости от того, как составлен ваш тест, создается впечатление, что цель вашего теста - проверить, правильно ли вызываются классовые зависимости 2 _step1 и _step2 в методе Execute().Это хороший первый тест для написания.

К сожалению, ваш тест не проверяет должным образом это условие.Поскольку вы устанавливаете ожидания на _step1 и _step2, вам необходимо изменить их с заглушек на макеты .

Кроме того, поскольку вы не устанавливаете ожидания на выходе, вы должны изменить их на заглушки из ложных сообщений или удалить их полностью, потому что вы звоните 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();
}

Я внес несколько дополнительных изменений для ясности:

Я переименовал ваш метод, чтобы более адекватно описать тест.Я обычно следую схеме: MethodUnderTest_Condition_ExpectedResult().Также я удалил Assert.IsNotNull(controller);, так как он не относится конкретно к тестируемому условию.

Существует, безусловно, больше тестов, которые вы можете захотеть написать для этого метода (Обеспечение вывода шага 1 является входом шага 2, например).Самое главное, не забывайте четко указывать в своем тесте, что именно вы тестируете, и делайте все возможное, чтобы протестировать одно условие за один раз.

...