InvalidOperationException с использованием насмешек Rhino и привязки данных
Я пишу некоторые модульные тесты для класса (в примере называется ClassUnderTest
) который имеет свойство, связывающее свойство со своей моделью. Как модель определяется с интерфейсом (IModel
), модель издевается над насмешкой Rhino Mocks.
Образец кода:
Интерфейс для модели:
public interface IModel : INotifyPropertyChanged
{
event PropertyChangedEventHandler PropertyChanged;
int SourceValue { get; set; }
}
класс, который должен быть испытан:
public class ClassUnderTest : DependencyObject
{
private IModel model;
public int TargetValue
{
get { return (int)GetValue(TargetValueProperty); }
set { SetValue(TargetValueProperty, value); }
}
public static readonly DependencyProperty TargetValueProperty = DependencyProperty.Register("TargetValue", typeof(int), typeof(ClassUnderTest), new PropertyMetadata(0));
public ClassUnderTest(IModel model)
{
this.model = model;
var b = new Binding("SourceValue") { Source = this.model, Mode = BindingMode.OneWay };
BindingOperations.SetBinding(this, TargetValueProperty, b);
}
}
Метод модульных испытаний:
[TestMethod]
public void TestMethod()
{
var repo = new MockRepository();
var modelMock = repo.StrictMock<IModel>();
const int expectedValue = 4;
IEventRaiser propertyChanged;
using (repo.Record())
{
propertyChanged = Expect.Call(delegate { modelMock.PropertyChanged += null; }).IgnoreArguments().GetEventRaiser();
Expect.Call(() => modelMock.PropertyChanged -= null).Constraints(Is.NotNull()).Repeat.Any();
Expect.Call(modelMock.SourceValue).Return(expectedValue).Repeat.Any();
}
using (repo.Playback())
{
var cuT = new ClassUnderTest(modelMock);
propertyChanged.Raise(modelMock, new PropertyChangedEventArgs("SourceValue"));
Assert.AreEqual(expectedValue, cuT.TargetValue);
}
}
Запускаю тестовый метод, все отлично работает. Возбуждение события "измененное свойство" на макете модели также вызывает изменение класса ClassUnderTest.
У меня сейчас проблема наблюдается только в режиме отладки. В конце теста я получаю исключение InvalidOperationException:
This action is invalid when the mock object is in verified state.:
at Rhino.Mocks.Impl.VerifiedMockState.MethodCall(IInvocation invocation, MethodInfo method, Object[] args)
at Rhino.Mocks.MockRepository.MethodCall(IInvocation invocation, Object proxy, MethodInfo method, Object[] args)
at Rhino.Mocks.Impl.RhinoInterceptor.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at IModelProxy2856c01157e54c29a4a7328a5a7ef52a.remove_PropertyChanged(PropertyChangedEventHandler value)
at System.ComponentModel.PropertyChangedEventManager.StopListening(Object source)
at System.ComponentModel.PropertyChangedEventManager.Purge(Object source, Object data, Boolean purgeAll)
at MS.Internal.WeakEventTable.Purge(Boolean purgeAll)
at MS.Internal.WeakEventTable.WeakEventTableShutDownListener.OnShutDown(Object target, Object sender, EventArgs e)
at MS.Internal.ShutDownListener.HandleShutDown(Object sender, EventArgs e)
Как я понимаю, это связано с тем, что привязка провоцирует отмену подписки, удаляя все объекты в конце теста, но макет уже находится в состоянии проверки и больше не допускает никакого взаимодействия.
Итак, вот мой ВОПРОС: есть ли способ избежать этого исключения или отказаться от подписки. Или я неправильно использую Rhino Mocks?
Спасибо за помощь
1 ответ
Вы пробовали это:
using (repo.Playback())
{
using (var cuT = new ClassUnderTest(modelMock))
{
propertyChanged.Raise(modelMock, new PropertyChangedEventArgs("SourceValue"));
Assert.AreEqual(expectedValue, cuT.TargetValue);
}
}