2017-09-06 45 views
2

从我的previous question,我知道我必须做Mock.SetupeventAggregatorMoq知道返回数据。设置moq与Caliburn事件聚合器的方法包装PublishOnUIThreadAsync

public void Navigate() { 
    eventAggregator.PublishOnUIThreadAsync(new MyEvent(5)); 
} 

以下工作正常用于覆盖这是不await ING上述包装方法和返回void

eventAggregatorMock.Verify(_ => _.Publish(It.IsAny<MyEvent>(), 
           It.IsAny<Action<System.Action>>()), Times.Once); 

那么,如果我在等待我的方法返回任务时如何设置。

public async Task Navigate() { 
    await eventAggregator.PublishOnUIThreadAsync(new MyEvent(5)); 
} 
+1

究竟什么是行不通的? –

+0

你遇到的错误是什么?还假定您提供了有关该方法的设置。 – Nkosi

回答

0

基于PublishOnUIThreadAsync扩展方法,它返回一个任务

/// <summary> 
/// Publishes a message on the UI thread asynchrone. 
/// </summary> 
/// <param name="eventAggregator">The event aggregator.</param> 
/// <param name="message">The message instance.</param> 
public static Task PublishOnUIThreadAsync(this IEventAggregator eventAggregator, object message) { 
    Task task = null; 
    eventAggregator.Publish(message, action => task = action.OnUIThreadAsync()); 
    return task; 
} 

你会注意到,任务由Publish正在执行的操作中分配。您需要调用该操作才能通过确保委托/操作被调用来分配任务。你可以在模拟方法的回调中做到这一点。

以下最简单的例子演示了如何做到这一点。请注意如何设置Publish以回调调用传入的Action参数。

[TestClass] 
public class MyTestClass { 

    [TestMethod] 
    public async Task _EventAggregator_Should_Publish_OnUIThread() { 
     //Arrange 
     MyEvent navigateEvent = null; 
     var eventAggregatorMock = new Mock<IEventAggregator>(); 
     eventAggregatorMock 
      .Setup(x => x.Publish(It.IsAny<MyEvent>(), It.IsAny<Action<System.Action>>())) 
      .Callback((object message, Action<System.Action> marshal) => { 
       navigateEvent = (MyEvent)message; 
       marshal(() => { });//Invoking action that would cause task to be assigned 
      }); 
     var sut = new MyClass(eventAggregatorMock.Object); 
     //Act 
     await sut.Navigate(); 
     //Assert 
     navigateEvent.Should().NotBeNull(); 
     eventAggregatorMock.Verify(_ => _.Publish(It.IsAny<MyEvent>(), 
      It.IsAny<Action<System.Action>>()), Times.Once); 
    } 

    public class MyEvent { 
     private int p; 

     public MyEvent(int p) { 
      // TODO: Complete member initialization 
      this.p = p; 
     } 

    } 
    public class MyClass { 
     IEventAggregator eventAggregator; 
     public MyClass(IEventAggregator eventAggregator) { 
      this.eventAggregator = eventAggregator; 
     } 

     public async Task Navigate() { 
      await eventAggregator.PublishOnUIThreadAsync(new MyEvent(5)); 
     } 
    } 
}