Недействительный вызов, последний вызов был использован или звонок не был выполнен
Я получаю эту ошибку, когда пытаюсь установить макет с PropertyBehavior()
:
System.InvalidOperationException: System.InvalidOperationException: Недействительный вызов, последний вызов был использован или звонок не был выполнен (убедитесь, что вы вызываете метод виртуального (С#)/Overridable (VB)).
Я пытаюсь использовать только Rhino Mocks 3.5 (Arrange, Act, Assert)
Вот мой код:
private IAddAddressForm form;
private AddAddressMediator mediator;
[TestInitialize()]
public void MyTestInitialize()
{
form = MockRepository.GenerateMock<IAddAddressForm>();
mediator = new AddAddressMediator(form);
// Make the properties work like a normal property
Expect.Call(form.OKButtonEnabled).PropertyBehavior();
//I tried this too. I still get the exception
//SetupResult.For(form.OKButtonEnabled).PropertyBehavior();
}
[TestMethod]
public void TestOKButtonEnabled()
{
form.OKButtonEnabled = true;
Assert.IsTrue(form.OKButtonEnabled);
}
Я знаю, что я мог бы использовать заглушку (и для кода выше, я должен), но я пытаюсь изучить Rhino Mocks.
В конце концов, я хочу, чтобы убедиться, что некоторые свойства имеют доступ к их значениям. (Любые подсказки о том, как проверить доступ к form.FirstName
(т.е. Был вызван приемник), также будут оценены.)
В случае необходимости, вот код IAddressForm
:
namespace AddressBook
{
public interface IAddAddressForm
{
string FirstName { get; set; }
string LastName { get; set; }
string Address1 { get; set; }
string State { get; set; }
string Address2 { get; set; }
string ZipCode { get; set; }
string City { get; set; }
bool OKButtonEnabled { get; set; }
}
}
В любом случае, я думал, что виртуальный не будет проблемой, поскольку я передаю интерфейс, но я явно что-то пропустил.
Ответы
Ответ 1
Никогда не использовался PropertyBehavior
раньше, но является ли этот синтаксис, который вы ищете?
form.Stub(x=>x.OKButtonEnabled).PropertyBehavior()
Rhino Mocks теперь полностью работает с помощью методов расширения. Единственный статический вызов, который я каждый сделаю, - это MockRepository.GenerateStub
.
Ответ 2
Вы упомянули использование заглушки вместо макета, но прежде чем вы меняете его, я бы заметил, что странно, я получаю исключение Invalid Call, когда я использовал GenerateStub, но не когда я использую GenerateMock.
View = MockRepository.GenerateStub<IAddressView>();
View.Stub(v => v.Message).PropertyBehavior();
Это вызывает исключение Invalid call и да, IAddressView.Message имеет getter и setter.
Ответ 3
Я получил эту ошибку, когда попытался установить ожидание по не виртуальному методу.
mockedObject.Expect(a => a.NonVirtualMethod()).Returns(null);
Ошибка исчезла, когда я сделал виртуальную версию NonVirtualMethod.
Ответ 4
Я думаю, вам нужно сделать MockRepository.ReplyAll() после того, как вы настроите все ожидания и перед тем, как начать использовать этот макет. Поэтому я предполагаю, что вам нужно переместить линию Expect.Call до того, как mediator = new AddAddressMediator (form);, и сразу же отложите ответ:
[TestInitialize()]
public void MyTestInitialize()
{
form = MockRepository.GenerateMock<IAddAddressForm>();
// Make the properties work like a normal property
Expect.Call(form.OKButtonEnabled).PropertyBehavior();
//I tried this too. I still get the exception
//SetupResult.For(form.OKButtonEnabled).PropertyBehavior();
MockRepository.ReplyAll();
mediator = new AddAddressMediator(form);
}
Ответ 5
Я столкнулся с этой проблемой, когда пытался вызвать свойство internal
(только для getter) для объекта в С#. В этом случае добавление .PropertyBehavior()
не помогло.
Мое решение состояло в том, чтобы извлечь логику из свойства и во внутренний метод, который затем я ввел в этот метод зависимости (как параметры).