tags:

views:

42

answers:

1

Hi All Wondering if its possible to Moq the Prism EventAggregator Let's take the EventAggregator Quickstart they have

     [TestMethod]
      public void PresenterPublishesFundAddedOnViewAddClick()
      {
         var view = new MockAddFundView();
         var EventAggregator = new MockEventAggregator();
         var mockFundAddedEvent = new MockFundAddedEvent();
         EventAggregator.AddMapping<FundAddedEvent>(mockFundAddedEvent);
         var presenter = new AddFundPresenter(EventAggregator);
         presenter.View = view;
         view.Customer = "99";
         view.Fund = "TestFund";
         view.PublishAddClick();
         Assert.IsTrue(mockFundAddedEvent.PublishCalled);
         Assert.AreEqual("99", mockFundAddedEvent.PublishArgumentPayload.CustomerId);
      }       

    I have tried to convert the above using moq but I get problems 

they have MockEventAggregator.How can I do that using Moq?

public class MockEventAggregator : IEventAggregator
{
    Dictionary<Type, object> events = new Dictionary<Type, object>();
    public TEventType GetEvent<TEventType>() where TEventType : EventBase
    {
        return (TEventType)events[typeof(TEventType)];
    }

    public void AddMapping<TEventType>(TEventType mockEvent)
    {
        events.Add(typeof(TEventType), mockEvent);
    }
}

Has anybody used MOQ and the EventAggregator are there any examples out there? Thanks a lot

EDIT

Following GrameF Answer I have added my code that still does not work.Can you help

            [TestMethod]
            public void PresenterPublishesFundAddedOnViewAddClick2()
            {

                //Arrange
                var view = new Mock<IAddFundView>();
                var fakeEventAggregator = new Mock<IEventAggregator>();
                var fakeMyEvent = new Mock<FundAddedEvent>();
                fakeEventAggregator.Setup(x => x.GetEvent<FundAddedEvent>()).Returns(fakeMyEvent.Object); 

                var presenter = new AddFundPresenter(fakeEventAggregator.Object) {View = view.Object};
                fakeMyEvent.Verify(x => x.Publish(It.IsAny<FundOrder>())); **//CRASHES** HERE



                //view.PublishAddClick();
                //view.Customer = "99";
                //view.Fund = "TestFund";

                //view.PublishAddClick();

                ////Assert 
                //Assert.IsTrue(mockFundAddedEvent.PublishCalled);
                //Assert.AreEqual("99", mockFundAddedEvent.PublishArgumentPayload.CustomerId);
                //Assert.AreEqual("TestFund", mockFundAddedEvent.PublishArgumentPayload.TickerSymbol);
            }
+1  A: 

Yes, it's possible, you just need to set it up to return a mock event on which you can verify that Publish or Subscribe was called:

var fakeEventAggregator = new Mock<IEventAggregator>();
var fakeMyEvent = new Mock<MyEvent>();

fakeEventAggregator.
    Setup(x => x.GetEvent<MyEvent>()).
    Returns(fakeMyEvent.Object);

var test = new Foo(fakeEventAggregator.Object);
test.PublishAnEvent();

fakeMyEvent.Verify(x => x.Publish(It.IsAny<MyEventArgs>()));
GraemeF
Excellent,Nearly there.Would it be too much to help create the first one and then I can take it from there. I have tried your implementation but got stuck when doing an equivalent of test.PublishAnEvent(); //Cannot seem to publishEvent as I cannot see presenter.View????? //Cannot seem to publishEvent as I cannot see presenter.View?????
var view = new Mock<IAddFundView>(); var fakeEventAggregator = new Mock<IEventAggregator>(); var fakeMyEvent = new Mock<FundAddedEvent>(); fakeEventAggregator.Setup(x => x.GetEvent<FundAddedEvent>()).Returns(fakeMyEvent.Object); var presenter = new AddFundPresenter(fakeEventAggregator.Object); //Cannot seem to publishEvent as I cannot see presenter.View?????
You shouldn't need the View in order to test this; there should be a method or `ICommand` or property (or whatever) exposed by the Presenter that causes the event to be published - this is the `PublishAnEvent` method in my example.
GraemeF
Hi thanks graham,AddFundView is private and in the usercontrol they do " public event EventHandler AddFund = delegate { };" void AddButton_Click(object sender, RoutedEventArgs e) { AddFund(this, null); } I suppose either it should be public or ..mmmm
Seems like your logic is in the wrong place to me - better to have it in the presenter so it's easy to test. You could move it into an `ICommand` exposed as a property on the presenter and then bind the button to the command.
GraemeF
Thanks for your help. That is not my logic I was testing Microsoft Prism Quickstart examples.