Wpf 使用Rhino模拟和数据绑定导致InvalidOperationException

Wpf 使用Rhino模拟和数据绑定导致InvalidOperationException,wpf,unit-testing,data-binding,rhino-mocks,propertychanged,Wpf,Unit Testing,Data Binding,Rhino Mocks,Propertychanged,我正在为一个类编写一些单元测试(在示例中称为ClassUnderTest),该类的属性绑定到其模型中的属性。由于模型是通过接口(IModel)定义的,因此模型由Rhino Mocks mock模拟 示例代码: 模型的接口: public interface IModel : INotifyPropertyChanged { event PropertyChangedEventHandler PropertyChanged; int SourceValue { get; set; }

我正在为一个类编写一些单元测试(在示例中称为
ClassUnderTest
),该类的属性绑定到其模型中的属性。由于模型是通过接口(
IModel
)定义的,因此模型由Rhino Mocks mock模拟

示例代码:

模型的接口:

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);
   }
}
据我所知,这是因为绑定通过在测试结束时处理所有对象来触发取消订阅,但mock已经处于验证状态,不再允许任何交互

所以我的问题是:有没有办法避免这个例外,或者联合国订阅。或者我用的犀牛模型不正确

感谢您的帮助

您是否尝试过以下方法:

using (repo.Playback())
{
    using (var cuT = new ClassUnderTest(modelMock))
    {
        propertyChanged.Raise(modelMock, new PropertyChangedEventArgs("SourceValue"));
        Assert.AreEqual(expectedValue, cuT.TargetValue);
    }
}

谢谢你的回答!很好的方法,我会尝试,如果它在我的情况下工作。
using (repo.Playback())
{
    using (var cuT = new ClassUnderTest(modelMock))
    {
        propertyChanged.Raise(modelMock, new PropertyChangedEventArgs("SourceValue"));
        Assert.AreEqual(expectedValue, cuT.TargetValue);
    }
}