Rhino Mocks: кажется, что минимальное время звонка не работает - PullRequest
0 голосов
/ 09 февраля 2011

Я использую Rhino-Mocks 3.6 в качестве мокинг-фреймворка в моих юнит-тестах и ​​у меня проблема с Repeat.Times():

Я хочу убедиться, что метод моего смоделированного объекта вызывается ровно три раза. Согласно документам я должен использовать Repeat.Times(3) или Repeat.Times(3, 3).

Но я замечаю, что он проверяет не менее трех вызовов, поэтому, когда я вызываю метод четыре раза, мой тест по-прежнему проходит. Сбой при вызове метода только два раза.

Вот мой код. Что-то не так с этим?

        MockRepository mocks = new MockRepository();
        IJobServiceEvent mockedJSE;
        using (mocks.Record())
        {
            mockedJSE = mocks.DynamicMock<IJobServiceEvent>();
            Expect.Call(() => mockedJSE.TransactionListChanged(null))
                .Repeat.Times(3);
        }

        using (mocks.Playback())
        {
            mockedJSE.TransactionListChanged(null);
            mockedJSE.TransactionListChanged(null);
            mockedJSE.TransactionListChanged(null);
            mockedJSE.TransactionListChanged(null);
        }

1 Ответ

2 голосов
/ 10 февраля 2011

Вам нужно использовать StrictMock. DynamicMock разрешит вызовы методов, которые не ожидаются. Таким образом, ваш вызов вашего метода ожидается три раза (что происходит). Но когда это происходит в четвертый раз, это не ошибка, поскольку вы определили его как DynamicMock (неожиданные вызовы разрешены).

Однако в долгосрочной перспективе использование StrickMock может быть головной болью при обслуживании, так как ваш тест слишком много знает о том, как пишется объект (так как вы должны смоделировать / заглушить все возможные вызовы).

Я бы порекомендовал синтаксис AAA (Arrange, Act, Assert) для ваших юнит-тестов. Ваш тест, описанный выше, может быть написан с использованием заглушки, но все же принудительно вызовите 3-пределный вызов для вашего метода:

IJobServiceEvent mockedJSE = MockRepository.GenerateStub<IJobServiceEvent>();

mockedJSE.TransactionListChanged(null);
mockedJSE.TransactionListChanged(null);
mockedJSE.TransactionListChanged(null);
mockedJSE.TransactionListChanged(null);

mockedJSE.AssertWasCalled(s => s.TransactionListChanged(null), o => o.Repeat.Times(3, 3));

UPDATE

Чтобы убедиться, что были сделаны только вызовы с определенными аргументами (хотя я думаю, что это в основном строгий макет, который может стать головной болью при обслуживании), трижды используйте параметр ограничений аргументов, чтобы убедиться, что эти вызовы выполнены. Затем создайте последний «AssertWasCalled», который игнорирует аргументы, и убедитесь, что он вызывался только три раза:

mockedJSE.AssertWasCalled(s => s.TransactionListChanged(null), o => o.IgnoreArguments().Repeat.Times(3, 3));
...