首页 > 解决方案 > 如何使用 moq 设置 Dispatcher InvokeAsync 方法

问题描述

我是单元测试的新手,并尝试通过编写包装器方法来模拟 Dispatcher,但我无法将该InvokeAsync方法设置为回调。

IDispatcher:

public interface IDispatcher
    {
        // other implementations

        DispatcherOperation InvokeAsync(Action action);

        DispatcherOperation<TResult> InvokeAsync<TResult>(Func<TResult> callback);
    }

DispatcherWrapper:

public class DispatcherWrapper : IDispatcher
{
        // Other implementations
        public DispatcherOperation InvokeAsync(Action action)
        {
            return this.UIDispatcher.InvokeAsync(action);
        }

        public DispatcherOperation<TResult> InvokeAsync<TResult>(Func<TResult> callback)
        {
            return this.UIDispatcher.InvokeAsync(callback);
        }
}

我尝试设置它的方式:

// this works as expected
this.mockDispatcher.Setup(x => x.BeginInvoke(It.IsAny<Action>())).Callback((Action a) => a());
// get an exception : System.ArgumentException : Invalid callback. Setup on method with parameters (Func<Action>) cannot invoke callback with parameters (Action).
this.mockDispatcher.Setup(x => x.InvokeAsync(It.IsAny<Func<It.IsAnyType>>())).Callback((Action a) => a());

用法:

var res = await this.dispatcher.InvokeAsync(() =>
                                             {
                                                // returns a result by computing some logic
                                             });

我只面临测试项目的问题。

标签: c#wpfnunitmoqdispatcher

解决方案


非泛型版本接受一个Action参数:

mockDispatcher.Setup(x => x.InvokeAsync(It.IsAny<Action>())).Callback((Action a) => a());

通用版本接受Func<TResult>

mockDispatcher.Setup(x => x.InvokeAsync(It.IsAny<Func<It.IsAnyType>>())).Callback(() => /* ... */ });

如果要Func<TResult>在回调中调用 ,则应指定类型参数或捕获Func<TResult>

Func<int> someFunc = () => 10;
mockDispatcher.Setup(x => x.InvokeAsync(It.IsAny<Func<It.IsAnyType>>())).Callback(() => someFunc());

推荐阅读