2

我需要做一些看起来很简单的事情,但我似乎无法实现。

我需要能够编写一个单元测试来调用任何订阅事件标记聚合器事件的操作和过滤委托。

例如,在我需要测试的类中,我有以下代码:

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

我希望我的测试调用this.OnViewRequestPublished方法和this.EventFilter方法。

我尝试EventAggregator在我的测试中使用该类的一个实例,但是如果没有调度程序存在,这些事件永远不会被触发,这在单元测试中没有帮助。

因此,我想使用 Rhino Mocks,但我不知道如何实现我所需要的。

谢谢

院长

4

2 回答 2

0

我自己解决了 - 这是我的代码(忽略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));

}
于 2011-02-25T09:16:02.247 回答
0
/// <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);
    }
}
于 2014-07-22T20:06:33.353 回答