C# 带Func的最小起订量<;Foo,Task<;列表<;酒吧>&燃气轮机&燃气轮机&燃气轮机;
情景: 我们正处在一个令人愉快的场景中,一个可怕的数据源需要一个神秘的语法。我们已经构建了“存储库”层,用于将简单参数(基本值)转换为目标的正确语法 我们希望进行单元测试:C# 带Func的最小起订量<;Foo,Task<;列表<;酒吧>&燃气轮机&燃气轮机&燃气轮机;,c#,unit-testing,moq,C#,Unit Testing,Moq,情景: 我们正处在一个令人愉快的场景中,一个可怕的数据源需要一个神秘的语法。我们已经构建了“存储库”层,用于将简单参数(基本值)转换为目标的正确语法 我们希望进行单元测试: 已应用正确的筛选器(可以通过检查repo的helper方法创建的字符串来完成) (模拟的)远程数据源只调用一次 在调用repo时,我们将远程数据源定义为返回的(模拟的)数据作为返回值传回 比如说 var expectedReturn = new List<Product> { new Product { Stoc
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);
磨合提供程序接口的定义:
Task<T> Run<T>(Func<IRemoteClient, Task<T>> action, string name);
任务运行(Func操作,字符串名称);
由于requestBuilder也被注入,我们可以很容易地评估请求在参数的数量和类型方面是否正确构建,但我们根本无法运行测试,因为Mock
调用无法完成设置,因此我们永远无法完成设置。我使用的是Moq 4.9.0,并且已经在.NET Core 2.1上进行了测试,以及使用.NET框架的LINQPad内部。它为我编译和运行没有任何问题。我能够运行mock安装程序,也能够对mock对象调用mocked方法,并检索预期的返回结果
以下是我的测试代码:
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; }
}
类程序
{
静态void Main(字符串[]参数)
{
var expectedReturn=new List{new Product{StockNumber=“123”};
var provider=new Mock();
供应商
.Setup(x=>x.Run(
It.IsAny(),
It.IsAny())
.ReturnsAsync(预期返回);
var result=provider.Object.Run(client=>client.GetAsync(null),“foo”);
Console.WriteLine(result.result[0].StockNumber);
}
}
公共接口IProvider
{
任务运行(Func操作,字符串名称);
}
公共接口IRemoteClient
{
任务GetAsync(对象请求);
}
公共类产品
{
公共字符串StockNumber{get;set;}
}
如果您更愿意执行.Returns(Task.FromResult(expectedReturn))
我的过于简化的示例似乎还有一些其他问题。你说得对,这似乎管用。我最终决定Run()。
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; }
}