воскресенье, 6 июля 2014 г.

Небольшая заметка по поводу RhinoMocks

RhinoMocks имеет разные варианты использования, и порой может слегка вводить в заблуждение. Я например, вот про этот аспект регулярно забываю, если долго не пишу тесты на Rhino: Стаб не имеет ожиданий и предназначен для тестирования состояния класса, но при желании ожидания для стаба можно установить и уже тестировать поведение. Если мы напишем:
    public interface IFoo
    {
        void Method1();
        void Method2();
    }

    public class TestedClass
    {
        private IFoo _foo;

        public TestedClass(IFoo foo)
        {
            _foo = foo;
        }

        public void TestedMethod()
        {
            _foo.Method1();
            _foo.Method2();
        }
    }

    [TestMethod]
    public void Test1()
    {
        MockRepository repository = new MockRepository();
            
        IFoo foo = repository.Stub<IFoo>();
        //IFoo foo = repository.StrictMock<IFoo>();
        //IFoo foo = repository.DynamicMock<IFoo>();
            
        //foo.Expect(x => x.Method1());
        //foo.Expect(x => x.Method2());        

        repository.ReplayAll();

        TestedClass test = new TestedClass(foo);
        test.TestedMethod();

        repository.VerifyAll();
    }
то тест благополучно пройдет, так как у стаба по умолчанию нету ожиданий. Но стоить только указать в ожиданиях вызов хоть одного метода, и stub начинает вести себя как самый настоящий StrictMock и в отличии от DynamicMock'a ругается на вызов любого непредусмотренного метода. Также, можно при желании "избавить от каких либо обязательств" StrickMock "застабив" все его методы :)
    IFoo foo = repository.StrictMock<IFoo>();
    foo.Stub(x => x.Method1());
    foo.Stub(x => x.Method2());  
и в таком случае нам уже не важно, вызывалось ли что-то в тестируем классе :)