如何使用 moq

问题描述

我是单元测试的新手,并试图通过编写包装器方法来模拟调度程序,但我无法设置 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
                                             });

我只遇到测试项目的问题。

解决方法

非通用版本接受一个 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());