Rhino Mocks: Repeat.Once () не работает?

Может ли кто-нибудь сказать мне, почему следующий тест не терпит неудач?

[Test]
public void uhh_what() {
    var a = MockRepository.GenerateMock<IPrebuiltNotifier>();
    a.Expect(x => x.Notify()).Repeat.Once();
    a.Notify();
    a.Notify();
    a.VerifyAllExpectations();
}

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


person George Mauer    schedule 20.05.2009    source источник
comment
Для справки в будущем (хотя Rhino mock уже устарел), я добавляю, что 'Stub' - 'Once' -'VerifyAllExpectations ', как в mock.Stub(x => x.Notify()).Repeat.Once();, также не работает должным образом. Вместо этого следует использовать AssertWasCalled.   -  person LosManos    schedule 23.01.2019


Ответы (2)


Уже существует ветка в группе RhinoMocks.

GenerateMock создает динамический макет. Динамический макет разрешает вызовы, которые не указаны (= ожидаемые). Если это произойдет, он просто вернет null (или значение по умолчанию для возвращаемого типа).

Примечание. Повторение - это спецификация поведения (например, заглушка), а не ожидание, даже если оно указано в ожидании.

Если вы не хотите, чтобы количество звонков превышало определенное, можно написать:

[Test]
public void uhh_what() 
{
    var a = MockRepository.GenerateMock<IPrebuiltNotifier>();
    a.Expect(x => x.Notify()).Repeat.Once();
    a.Stub(x => x.Notify()).Throw(new InvalidOperationException("gotcha"));
    a.Notify();

    // this fails
    a.Notify();

    a.VerifyAllExpectations();
}

Or

[Test]
public void uhh_what() 
{
    var a = MockRepository.GenerateMock<IPrebuiltNotifier>();
    a.Notify();
    a.Notify();

    // this fails
    a.AssertWasCalled(
      x => x.Notify(), 
      o => o.Repeat.Once());
}
person Stefan Steinegger    schedule 20.05.2009
comment
ой! Я не знал, что у AssertWasCalled был второй аргумент, в котором вы могли бы сделать больше спецификаций, это все меняет! - person George Mauer; 20.05.2009
comment
То же самое и с PartialMock, если вы когда-нибудь наступите на него. - person Dennis; 13.09.2011
comment
Первое решение (когда вы вызываете исключение) приведет к сбою теста, если Notify вызывается более одного раза. Однако, если он вызывается только один раз (по крайней мере, то, что, как я предполагаю, должен делать тестируемый код), тест не пройдет должным образом, потому что он ожидает второго вызова Notify, который никогда не поступит. Установите a.Expect(x => x.Notify()).Repeat.Once(), а затем a.Stub(x => x.Notify()).Throws(...), чтобы выполнить задание. - person geoffmazeroff; 27.09.2011
comment
@geoffmazeroff: ты прав. Этот ответ существует более 2-х лет и его никто так и не узнал ... Спасибо, исправил. - person Stefan Steinegger; 28.09.2011

При использовании GenerateMock (или вообще с Dynamic Mocks) я всегда мысленно вставляю следующее:

a.Expect (x => x.Notify ()). Повторить. * [AtLeast] * Once ();

person Sam Shiles    schedule 23.12.2010