Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使模拟在更改时触发属性更改_C#_Mocking_Rhino Mocks_Propertychanged - Fatal编程技术网

C# 使模拟在更改时触发属性更改

C# 使模拟在更改时触发属性更改,c#,mocking,rhino-mocks,propertychanged,C#,Mocking,Rhino Mocks,Propertychanged,我使用的是Rhinomock,我有一个Mock,它有一个我需要作为真实属性的属性——在设置时更新它的值,并且在属性更改时触发PropertyChanged 模拟对象的接口本质上是这样的: public interface IFoo { event PropertyChangedEventHandler PropertyChanged; int Bar { get; set; } } 创建模拟时,我设置PropertyBehavior-这使它实际更新其伪造值: var mocks

我使用的是Rhinomock,我有一个Mock,它有一个我需要作为真实属性的属性——在设置时更新它的值,并且在属性更改时触发PropertyChanged

模拟对象的接口本质上是这样的:

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();
var mocks=new MockRepository();
var fakeFoo=mocks.DynamicMock();
SetupResult.For(fakeFoo.Bar).PropertyBehavior();

但当我更新值PropertyChanged时,不会触发。现在,该接口没有实现INotifyPropertyChanged接口,因为它是一个接口。。如何使PropertyChanged被触发

我不是Rhinomock方面的专家,但我不会尝试使用我所知道的任何模拟框架(TypeMock我知道得最多)

我将实现如下内容:

public class FooFake: IFoo
{
    public event PropertyChangedEventHandler PropertyChanged;
    int _bar;
    public int Bar
    {
       set
       {
           if( PropertyChanged != null )
               PropertyChanged();
           _bar = value;
       }
       get
       {
          return _bar;
       }
    }
}

对不起。没有什么真正聪明的。但是我喜欢这种存根,因为它们可以恢复。

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

在一个测试中,您只需验证您的听力类是否按照设计对
PropertyChanged
事件做出反应。您不关心是什么导致该测试中的属性发生更改:

[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; } );
}
[测试]
public void在属性更改时更新标题
{
var foo=MockRepository.GenerateStub();
foo.Bar=“sometestvalue1”;
var欠测试=新欠测试(foo);
//在模拟对象上更改属性并引发PropertyChanged事件
foo.Bar=“sometestvalue2”;
foo.Raise(x=>x.PropertyChanged+=null,
福,
新的房地产变更(Bar);
//断言被测试的类的反应与设计一致
AreEqual(“sometestvalue2”,underTest.Caption);
//或者如果预期的状态变化难以验证,
//您可以验证该属性是否至少已读取
调用了foo.assertwas(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);
}
[测试]
公共无效重置\u清除\u Foo\u Bar()
{
var foo=MockRepository.GenerateStub();
foo.Bar=“非空字符串”;
var欠测试=新欠测试(foo);
underTest.Reset();
//断言被测试的类按照设计更新了Bar属性
Assert.IsNull(foo.Bar);
}

这样,就没有必要像您正在尝试的那样将真实逻辑放入模拟对象中。这确实需要为可测试性设计类;很难将此类测试添加到现有类中。因此采用了。

+1,但这不是存根。手动创建的简化实现的单元测试术语是“假的”。谷歌测试博客上的这篇文章给出了一些很好的定义:马丁·福勒的这篇文章:你是对的。我必须改变我的习惯,把它叫做存根!我现在将示例从FooStub更改为foosfake。