2009-07-27 5 views
2

컨트롤러에 대한 단위 테스트를하고 비즈니스 구성 요소를 조롱하고 있습니다. 브리티시 컬럼비아에는 컨트롤러가 구성되었을 때 청취자가 듣는 공개 이벤트가 있습니다.조롱 된 객체의 이벤트를 수신하려면 어떻게해야합니까?

내가 겪고있는 문제는 다음과 같은 예상 오류가 계속 발생한다는 것입니다. "IBC.add_MessageRaised (MessageEventHandler) Expected # : 1 Actual # : 0".

그러나 내 테스트에는 그런 종류의 기대가 없습니다. 컨트롤러가 조롱 된 객체 (이 경우에는 BC)에서 이벤트를 수신하도록 설정하는 것과 관련이 있는지 궁금합니다. Controller에게 모의에서 오는 이벤트를 청취 할 수있는 또 다른 방법이 있습니까?

MessageRaised 이벤트를 발생시키는 모의 방법을 생각하려고합니다. 그러나 그것은 또 다른 질문 일 수 있습니다. 여기

코드입니다 :

비즈니스 구성 요소 인터페이스

public interface IBC 
{ 
    event MessageEventHandler MessageRaised; 
    XmlDocument GetContentXml(string path); 
} 

컨트롤러

private readonly IBC _bc; 

public Controller(IBC bc) 
{ 
    _bc = bc; 
    _bc.MessageRaised += MessageWatch; 
} 
private void MessageWatch(object sender, MessageEventArgs e) 
{ 
    if (MessageRaised != null) 
     MessageRaised(sender, e); 
} 

그것은 다음과 같은 코드가 mock 객체를 사용하는 것 같다

MockRepository Mockery = new MockRepository(); 
TFactory _tFac; 
IView _view; 
Presenter _presenter = new Presenter(); 
IBC _bc = Mockery.DynamicMock<IBC>(); 
Controller _controller = new Controller(_bc); 
_tFac = new TFactory(Mockery); 
_tFac.Create(ref _view, ref _presenter, ref _controller); 

[Test] 
public void View_OnGetContentXmlButtonClick_Should_SetXmlInView() 
{ 
    //SETUP 
    XmlDocument xmlDocument = new XmlDocument(); 
    using (Mockery.Record()) 
    { 
     SetupResult.For(_view.FilePath).Return("C:\Test.txt"); 
     Expect.Call(_bc.GetContentXml("C:\Test.txt")).Return(xmlDocument); 
     _view.Xml = xmlDocument.InnerXml; 
    } 

    //EXECUTE 
    using (Mockery.Playback()) 
    { 
     _presenter.View_OnGetContentXmlButtonClick(); 
    } 
} 

답변

0

나는 몇 가지를 결합하여 작동하도록있어 (어떻게 작동하는지 완전히 확실하지,하지만 않습니다) :

IEventRaiser _raiser; 
MockRepository Mockery = new MockRepository(); 
TFactory _tFac; 
IView _view; 
Presenter _presenter = new Presenter(); 
IBC _bc = Mockery.DynamicMock<IBC>(); 
_bc.MessageRaised += null; 
_raiser = LastCall.GetEventRaiser(); 
Controller _controller = new Controller(_bc); 
Mockery.BackToRecord(_bc,BackToRecordOptions.None); 
_tFac = new TFactory(Mockery); 
_tFac.Create(ref _view, ref _presenter, ref _controller); 

이것은 질문 일에 시험뿐만 아니라 나를는 인상시키는했다 다른 테스트에서 Mock 객체의 이벤트 :

[Test] 
public void View_OnGetContentXmlButtonClick_When_FileDoesNotExist_Should_RelayMessage() 
{ 
    //SETUP 
    XmlDocument xmlDocument = new XmlDocument(); 
    using (Mockery.Record()) 
    { 
     SetupResult.For(_view.FilePath).Return("C:\Test.txt"); 
     Expect.Call(_bc.GetContentXml("C:\Test.txt")).Return(null); 
     _view.Xml = xmlDocument.InnerXml; 
     _view.Message = MESSAGE_FILE_NOT_EXIST; 
    } 

    //EXECUTE 
    using (Mockery.Playback()) 
    { 
     _presenter.View_OnGetContentXmlButtonClick(); 
     _raiser.Raise(_bc, new MessageEventArgs(MESSAGE_FILE_NOT_EXIST)); 
    } 
} 

희망이 다른 유용한 정보 이 경우

 port.DataPacketReceived += null; 
     packetReceivedRaiser = 
      LastCall.IgnoreArguments().Repeat.Any().GetEventRaiser(); 

는, 포트 DataPacketReceived라는 이벤트와 모의 객체이다 : 나는 모의 객체에서 이벤트를 제기 처리 방법은 다음과

3

단위 테스트 당신은이 같은 모의 개체를 사용하는

Controller _controller = new Controller(_bc); 

: d는, 그것을 사용하여, 기대가 기록됩니다

_bc.MessageRaised += MessageWatch; 

결과를, 당신은 기대를 설정 한 그 이벤트 핸들러 _bc.MessageRaised에 추가됩니다. 이는 재생 블록에서 발생하지 않으므로 오류가 발생합니다.

this question도 개체가 레코드 상태가 될 때 참조하십시오. 솔직히 말해, 객체가 암시 적으로 레코드 상태를 입력하는 경우 명시적인 레코드 구문이있는 이유를 이해할 수 없습니다.

+0

고맙습니다!다른 질문은 BackToRecord() 메소드에 대해 알지 못해서 도움이되었습니다. –

0

입니다.

이상하게도 필자는 모의 객체를 테스트 모드로 전달하기 전에 항상 재생 모드로 설정하려고합니다. 이렇게하면 "예기치 않은 기대"를 피할 수 있습니다.

관련 문제