场景:
我们正处于一个可怕的数据源需要神秘语法的可爱场景中。我们构建了“存储库”层,将简单参数(原始值)转换为目标的正确语法。
我们想要进行单元测试:
- 已应用正确的过滤器(可以通过检查存储库的辅助方法创建的字符串来完成)
- (模拟的)远程数据源仅被调用一次
- 当我们调用存储库时,我们定义的远程数据源返回的(模拟)数据将作为返回值传回。
例如
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 帖子,但找不到它为什么不起作用的原因。
在正常使用中,Repo 将使用如下内容:
provider.Run(x => x.GetAsync<List<Product>>(requestBuilder.Request), "foo")
provider接口(interface)中run的定义:
Task<T> Run<T>(Func<IRemoteClient, Task<T>> action, string name);
由于 requestBuilder 也被注入(inject),我们可以很容易地根据参数的数量和类型评估请求是否正确构建,但我们根本无法运行测试,因为 Mock
调用设置失败,因此我们永远无法到达那里。
最佳答案
我使用的是 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; }
}
关于c# - 起订量与 Func<Foo, Task<List<Bar>>>>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51867124/