The mocks cast invokes the PropertyChanged property when changing

I use RhinoMocks, and I have a Mock that has a property that I need to maintain as a real property - updating its value when it is set, and also run PropertyChanged when the property changes.

The mocking object's interface is essentially this:

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

When creating the layout, I set the PropertyBehavior property - which actually updates its fake value:

 var mocks = new MockRepository(); var fakeFoo = mocks.DynamicMock<IFoo>(); SetupResult.For(fakeFoo.Bar).PropertyBehavior(); 

But when I update the value, the PropertyChanged property does not start. Now the interface does not implement the INotifyPropertyChanged interface, since it is an interface. How can I run PropertyChanged?

+4
source share
2 answers

The role of the listener and the mutator can sometimes be combined in one class (for example, in the adapter), but both roles should not be tested together.

In one test, you simply confirm that your listening class responds to the PropertyChanged event as it was designed. It doesn't matter to you what the property changed in this test:

 [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; } ); } 

In another test, you verify that your class plays the role of a mutator in accordance with its construction:

 [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); } 

Thus, you never need to introduce real logic into your mock objects, as you are trying to do. This requires that you design your classes for validation; it’s hard to add such tests to existing classes. Therefore, the practice is test driven development .

+7
source

I am not an expert in RhinoMocks, but I would not do it with any layout structure that I know (TypeMock I know the most).

I would do something like:

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

Unfortunately. Nothing really smart. But I like this stub because they can be reused.

+1
source

Source: https://habr.com/ru/post/1302796/


All Articles