Rhino Mocks и PRISM EventAggregator - PullRequest
       10

Rhino Mocks и PRISM EventAggregator

2 голосов
/ 24 февраля 2011

Мне нужно сделать что-то, что кажется довольно простым, но я не могу этого достичь.

Мне нужно иметь возможность написать модульный тест, который вызывает действие и фильтрует делегатов любой подписки на событие eventaggregator.

Например, в моем классе, который нужно проверить, у меня есть следующий код:

this.eventAggregator.GetEvent<RiskDataViewsJournalChangedEvent>().Subscribe(
    this.OnViewRequestPublished, ThreadOption.UIThread, false, this.EventFilter);

и я хочу, чтобы мой тест вызывал метод this.OnViewRequestPublished и метод this.EventFilter.

Я пытался использовать экземпляр класса EventAggregator в моем тесте, но события никогда не запускаются без присутствия диспетчера, что бесполезно в модульном тесте.

Поэтому я хочу использовать Rhino Mocks, но не могу понять, как добиться того, что мне нужно.

Спасибо

Dean

Ответы [ 2 ]

0 голосов
/ 23 июля 2014
/// <remarks>Event.Publish does not work in unit tests when subscribed with ThreadOption.UIThread </remarks>
public void FireGlobalEvent<TEvent, TEventArgs>(TEventArgs args)
    where TEvent : CompositePresentationEvent<TEventArgs>, new ()
{
    var globalEvent = GetInstance<IEventAggregator>().GetEvent<TEvent>();
    var subscriptions = (IEnumerable)globalEvent.GetType().GetProperty("Subscriptions", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(globalEvent);
    foreach (DispatcherEventSubscription<TEventArgs> subscription in subscriptions.Cast<object>().ToArray())
    {
        subscription.Action.Invoke(args);
    }
}
0 голосов
/ 25 февраля 2011

Я решил это сам - вот мой код (игнорируйте ссылки EventToken, это то, что я сам создал для фильтрации событий).

[Test]
public void RiskDataGridViewModelEventSubscriptionTests()
{
    // event token
    var tok = new EventToken();

    // mock event aggregator
    var agg = MockRepository.GenerateStub<IEventAggregator>();

    // my target class subscribes to 3 events in its constructor
    var evt1 = MockRepository.GenerateStub<RiskDataViewsJournalChangedEvent>();
    var evt2 = MockRepository.GenerateStub<RiskDataViewsJournalChangingEvent>();
    var evt3 = MockRepository.GenerateStub<RiskDataViewRequestPublishEvent>();

    // ensure mocked event classes are returned
    agg.Stub(x => x.GetEvent<RiskDataViewsJournalChangedEvent>()).Return(evt1);
    agg.Stub(x => x.GetEvent<RiskDataViewsJournalChangingEvent>()).Return(evt2);
    agg.Stub(x => x.GetEvent<RiskDataViewRequestPublishEvent>()).Return(evt3);

    // instantiate target class - in my class the events get subscribed to in the constructor
    new RiskDataGridViewModel(agg, tok, null);

    // get the parameters passed to the subscribe method
    var args1 = evt1.GetArgumentsForCallsMadeOn(s => s.Subscribe(null));
    var args2 = evt2.GetArgumentsForCallsMadeOn(s => s.Subscribe(null));
    var args3 = evt3.GetArgumentsForCallsMadeOn(s => s.Subscribe(null));

    // invoke filters
    ((Predicate<EventParameter<IRiskDataViewResultItem>>)args1[0][3]).Invoke(new EventParameter<IRiskDataViewResultItem>(null, tok));
    ((Predicate<EventParameter>)args2[0][3]).Invoke(new EventParameter(null, tok));
    ((Predicate<EventParameter<ViewRequest>>)args3[0][3]).Invoke(new EventParameter<ViewRequest>(null, tok));

    // invoke methods
    ((Action<EventParameter<IRiskDataViewResultItem>>)args1[0][0]).Invoke(new EventParameter<IRiskDataViewResultItem>(null, tok));
    ((Action<EventParameter>)args2[0][0]).Invoke(new EventParameter(null, tok));
    ((Action<EventParameter<ViewRequest>>)args3[0][0]).Invoke(new EventParameter<ViewRequest>(null, tok));

}
...