从我的previous question,我了解到我必须Mock.Setup
让eventAggregatorMoq
知道返回数据。
public void Navigate() {
eventAggregator.PublishOnUIThreadAsync(new MyEvent(5));
}
以下内容适用于覆盖上述包装方法,该方法不是await
并返回void
。
eventAggregatorMock.Verify(_ => _.Publish(It.IsAny<MyEvent>(),
It.IsAny<Action<System.Action>>()), Times.Once);
那么,如果我正在等待返回Task的方法,我该怎么设置呢。
public async Task Navigate() {
await eventAggregator.PublishOnUIThreadAsync(new MyEvent(5));
}
答案 0 :(得分: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));
}
}
}