2009-07-27 4 views
2

Ich mache einige Komponententests für einen Controller, und ich verspotte die Business-Komponente. Das BC hat ein öffentliches Ereignis, auf das der Controller hört, wenn der Controller aufgebaut wird.Wie höre ich das Ereignis eines verspotteten Objekts?

Das Problem, das ich habe, ist, dass ich einen Erwartungsfehler bekomme, der besagt: "IBC.add_MessageRaised (MessageEventHandler) Erwartet #: 1 Actual #: 0".

Allerdings habe ich in meinem Test keine solche Erwartung. Ich frage mich, ob es damit zu tun hat, den Controller so einzustellen, dass er auf ein Ereignis auf einem verspotteten Objekt hört (in diesem Fall das BC). Gibt es einen anderen Weg, wie ich den Controller dazu bringen kann, ein Ereignis zu hören, das von einem Mock kommt?

Ich versuche auch über eine Möglichkeit nachzudenken, wie der Mock das MessageRaised-Ereignis auslösen kann, aber das könnte eine andere Frage sein. Hier

ist der Code:

Business Component-Schnittstelle

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

-Controller

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

Einheit Test

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

Antwort

0

habe ich es durch die Kombination von ein paar Dinge zu arbeiten (nicht ganz sicher, wie es funktioniert, aber es funktioniert):

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

Dies machte den Test in der Frage der Arbeit, sowie ich einen Stich gelassen erhöhen Ereignis aus dem Mock-Objekt in anderen Tests, wie:

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

Hoffe andere finden das nützlich!

3

Es scheint der folgende Code ein Mock-Objekt ein verwendet d, indem Sie es bewirkt eine Erwartung zu erfassen:

Controller _controller = new Controller(_bc); 

Sie das Mock-Objekt wie folgt aus:

_bc.MessageRaised += MessageWatch; 

Als Ergebnis haben Sie eine Erwartung aufgebaut, dass ein Event-Handler wird zu _bc.MessageRaised hinzugefügt. Dies passiert nicht im Wiedergabeblock, daher wird ein Fehler ausgelöst.

Siehe auch this question, wenn ein Objekt in den Aufzeichnungsstatus eintritt. Um ehrlich zu sein, verstehe ich auch nicht, warum es eine explizite Record-Syntax gibt, wenn Objekte implizit in den Record-State gelangen.

+0

Vielen Dank!Die andere Frage half mir, da ich die BackToRecord() Methode nicht kannte. –

0

Hier ist, wie ich mit dem Anheben Ereignisse von einem Mock-Objekt behandeln:

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

In diesem Fall Port ein Mock-Objekt mit einem Ereignisse ist DataPacketReceived genannt.

Im Idealfall versuche ich immer, meine Mock-Objekte in den Wiedergabemodus zu versetzen, bevor sie an das getestete System übergeben werden. Dies vermeidet "unerwartete Erwartungen".

Verwandte Themen