场景:
我们处在一个可怕的数据源中,需要一个神秘的语法。我们已经构建了“存储库”层,以将简单参数(原始值)转换为目标的正确语法。
我们要对该单元进行测试:
例如
var expectedReturn = new List<Product> { new Product { StockNumber = "123" } };
provider.Setup(x => x.Run(It.IsAny<Func<IRemoteClient, Task<List<Product>>>>(),
It.IsAny<string>())).ReturnsAsync(expectedReturn);
Moq在Setup
行中失败,并带有NotSupportedException
。我可能已经阅读了十几篇或更多的SO帖子,并且找不到为什么它不起作用。
在正常使用中,存储库将使用类似以下内容的
:provider.Run(x => x.GetAsync<List<Product>>(requestBuilder.Request), "foo")
在provider
界面中运行的定义:
Task<T> Run<T>(Func<IRemoteClient, Task<T>> action, string name);
由于还注入了requestBuilder,因此我们可以很容易地评估出,就参数的数量和类型而言,请求是否正确构建,但是由于Mock
调用失败,我们根本无法运行测试设置,所以我们永远都无法实现。
答案 0 :(得分:2)
我正在使用Moq 4.9.0,并且已经在.NET Core 2.1以及使用.NET Framework的LINQPad内部进行了测试。它可以为我编译并运行,没有任何问题。我可以运行模拟设置,也可以在模拟对象上调用模拟方法,并检索预期的返回结果。
以下是我的测试代码:
class Program
{
static void Main(string[] args)
{
var expectedReturn = new List<Product> { new Product { StockNumber = "123" } };
var provider = new Mock<IProvider>();
provider
.Setup(x => x.Run(
It.IsAny<Func<IRemoteClient, Task<List<Product>>>>(),
It.IsAny<string>()))
.ReturnsAsync(expectedReturn);
var result = provider.Object.Run(client => client.GetAsync<List<Product>>(null), "foo");
Console.WriteLine(result.Result[0].StockNumber);
}
}
public interface IProvider
{
Task<T> Run<T>(Func<IRemoteClient, Task<T>> action, string name);
}
public interface IRemoteClient
{
Task<T> GetAsync<T>(object request);
}
public class Product
{
public string StockNumber { get; set; }
}