2010-03-01 2 views
4

RhinoMock을 사용하고 있으며 실제 속성으로 동작해야하는 속성이있는 모의이 있습니다. 설정시 값을 업데이트하고 속성이 변경되면 PropertyChanged를 트리거합니다.변경시 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(); 

을하지만 업데이트 PropertyChanged 값은 트리거되지 않습니다. 이제는 인터페이스가 INotifyPropertyChanged 인터페이스를 구현하지 않습니다. 어떻게 PropertyChanged를 트리거 할 수 있습니까?

답변

7

청취자와 뮤 테이타의 역할은 때때로 동일한 클래스 (예 : 어댑터)에서 결합 될 수 있지만 두 역할을 함께 테스트해서는 안됩니다.

하나의 테스트에서 청취 클래스가 설계된대로 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; }); 
} 

다른 테스트에서를, 당신은 당신의 클래스가 뮤 테이터 역할을하고 있는지 확인합니다

[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의 관행.

1

저는 RhinoMocks의 전문가는 아니지만, 제가 아는 모의 프레임 워크 (TypeMock은 내가 가장 잘 알고 있습니다)를 사용하여 그렇게하려고하지는 않습니다.

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

죄송합니다 :

내가 좋아하는 뭔가를 구현하는 것입니다. 정말 영리한 건 없어요. 하지만 나는 이런 종류의 스텁을 좋아할 수 있습니다.

+1

+1하지만 이것은 스텁이 아닙니다. 수동으로 생성되고 단순화 된 구현의 단위 테스트 기간은 "가짜"입니다. Google 테스트 블로그의이 게시물은 몇 가지 좋은 정의를 제공합니다. http://googletesting.blogspot.com/2008/06/tott-friends-you-can-depend-on.html이 기사는 Martin Fowler가 작성했습니다. http : // martinfowler.com/articles/mocksArentStubs.html –

+0

당신 말이 맞아요. 그 스텁 전화 습관을 바꿔야 해! 예제를 FooStub에서 FooFake로 변경했습니다. – Enceradeira