问题
Consider the below method that updates a person and publishes an event through the PRISM EventAggregator to indicate that the person has been updated.
I would like to unit test that the message is sent with the correct payload. In this case that would mean the correct personId.
public void UpdatePerson(int personId)
{
// Do whatever it takes to update the person
// ...
// Publish a message indicating that the person has been updated
_eventAggregator
.GetEvent<PersonUpdatedEvent>()
.Publish(new PersonUpdatedEventArgs
{
Info = new PersonInfo
{
Id = personId,
UpdatedAt = DateTime.Now
};
});
}
I know that I can create a substitute for the event aggregator:
var _eventAggregator = Substitute.For<IEventAggregator>();
However, I don't know how to detect when a message is sent and how to check its payload.
回答1:
I'm not an experienced unit tester so I'm not sure this is the correct unit test to write. But anyway, this is how I tested it so far and it seems to do what I want.
[Test]
public void TestPersonUpdateSendsEventWithCorrectPayload()
{
// ARRANGE
PersonUpdatedEventArgs payload = null;
_eventAggregator
.GetEvent<PersonUpdatedEvent>()
.Subscribe(message => payload = message);
// ACT
_personService.UpdatePerson(5);
// ASSERT
payload.Should().NotBeNull();
payload.Id.Should().Be(5);
}
Feedback welcome.
回答2:
You can actually substitute away the event aggregator like this:
public class ToBeTested
{
private readonly IEventAggregator _eventAggregator;
public ToBeTested( IEventAggregator eventAggregator )
{
_eventAggregator = eventAggregator;
}
public void DoStuff()
{
_eventAggregator.GetEvent<OneEvent>().Publish( "test" );
}
}
public class OneEvent : PubSubEvent<string>
{
}
[TestFixture]
internal class Test
{
[Test]
public void DoStuffTest()
{
var myEvent = new MyOneEvent();
var myEventAggregator = Substitute.For<IEventAggregator>();
myEventAggregator.GetEvent<OneEvent>().Returns( myEvent );
var toBeTested = new ToBeTested( myEventAggregator );
toBeTested.DoStuff();
Assert.That( myEvent.ReceivedPayload, Is.EqualTo( "test" ) );
}
private class MyOneEvent : OneEvent
{
public override void Publish( string payload )
{
ReceivedPayload = payload;
}
public string ReceivedPayload
{
get;
private set;
}
}
}
Note the fake event class that's foisted on the subject under test to get access to the payload.
回答3:
Just add a subscriber to your unit test and check the result of the delegate. See Prism's IEventAggregator unit tests as an example
https://github.com/PrismLibrary/Prism/blob/master/Source/Prism.Tests/Events/PubSubEventFixture.cs#L14
来源:https://stackoverflow.com/questions/35868184/nsubstitute-vs-prism-eventaggregator-assert-that-calling-a-method-triggers-even