c# - 起订量与 Func<Foo, Task<List<Bar>>>>

标签 c# unit-testing moq

场景:

我们正处于一个可怕的数据源需要神秘语法的可爱场景中。我们构建了“存储库”层,将简单参数(原始值)转换为目标的正确语法。

我们想要进行单元测试:

  1. 已应用正确的过滤器(可以通过检查存储库的辅助方法创建的字符串来完成)
  2. (模拟的)远程数据源仅被调用一次
  3. 当我们调用存储库时,我们定义的远程数据源返回的(模拟)数据将作为返回值传回。

例如

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/

相关文章:

c# - 如何查询一个域的用户是否是另一个AD域中的组的成员?

c# - 无法正确模拟方法

c# - 这还是Mock上的验证测试吗?

c# - 类中的组方法

c# - 我可以利用哪个 Task<T> 扩展来递归等待其他任务?

c# - 在 .NET 中,BigInteger.ToString() 返回的字符串是否反射(reflect)了 BigInteger 的完整精度?

unit-testing - Entity Framework 4.1 RC POCO - 对生成的字段名称进行单元测试

java - Java 项目中的 Android 类

python-3.x - 我可以在测试 Flask 应用程序功能时使用模拟吗?

c# - 用于对我无法轻松创建的返回类型进行单元测试的选项