我正在使用 RhinoMocks,我有一个 Mock,它有一个属性,我需要作为一个真实的属性 - 在设置时更新它的值,并在属性更改时触发 PropertyChanged。

被模拟对象的接口(interface)本质上是这样的:

public interface IFoo
{
    event PropertyChangedEventHandler PropertyChanged;
    int Bar { get; set; }
}

创建模拟时,我设置了 PropertyBehavior - 这使得它实际上更新了它的伪造值:
var mocks = new MockRepository();
var fakeFoo = mocks.DynamicMock<IFoo>();
SetupResult.For(fakeFoo.Bar).PropertyBehavior();

但是当我更新值 PropertyChanged 不会被触发。现在,该接口(interface)没有实现 INotifyPropertyChanged 接口(interface),因为它是一个接口(interface)。我怎样才能触发 PropertyChanged?

最佳答案

监听器和修改器的角色有时可以组合在同一个类中(例如在适配器中),但不应一起测试这两个角色。

在一项测试中,您只需验证您的监听类是否按照设计对 PropertyChanged 事件使用react。您不关心是什么导致该测试中的属性发生变化:

[Test]
public void Updates_Caption_when_Bar_PropertyChanged()
{
   var foo = MockRepository.GenerateStub<IFoo>();
   foo.Bar = "sometestvalue1";
   var underTest = new UnderTest(foo);

   // change property and raise PropertyChanged event on mock object
   foo.Bar = "sometestvalue2";
   foo.Raise(x=>x.PropertyChanged+=null,
       foo,
       new PropertyChangedEventArgs("Bar"));

   // assert that the class under test reacted as designed
   Assert.AreEqual("sometestvalue2", underTest.Caption);

   // or if the the expected state change is hard to verify,
   // you might just verify that the property was at least read
   foo.AssertWasCalled(x => { var y = foo.Bar; } );
}

在另一个测试中,您验证您的类是否按设计发挥了它的 mutator 角色:
[Test]
public void Reset_clears_Foo_Bar()
{
   var foo = MockRepository.GenerateStub<IFoo>();
   foo.Bar = "some string which is not null";
   var underTest = new UnderTest(foo);

   underTest.Reset();

   // assert that the class under test updated the Bar property as designed
   Assert.IsNull(foo.Bar);
}

这样,就没有必要像您尝试做的那样将真正的逻辑放入您的模拟对象中。这确实要求您设计类以实现可测试性;很难将此类测试添加到现有类中。因此, test driven development 的做法。

关于c# - 使模拟在更改时触发 PropertyChanged,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2358966/

10-11 04:39