Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 单元测试返回类型I can';不容易创造_C#_Unit Testing_Moq - Fatal编程技术网

C# 单元测试返回类型I can';不容易创造

C# 单元测试返回类型I can';不容易创造,c#,unit-testing,moq,C#,Unit Testing,Moq,我需要对一个方法进行单元测试,该方法返回一个我不能轻易伪造或实例化的类型。该类型实现了IQueryable,我原本认为可以利用它发挥自己的优势,但现在我不知道该如何实现 例如: public sealed class MyTrickyClass<T> : IQueryable<T> { ... } public MyTrickyClass<T> GetData() { return repository.GetAllData(); } 公共

我需要对一个方法进行单元测试,该方法返回一个我不能轻易伪造或实例化的类型。该类型实现了
IQueryable
,我原本认为可以利用它发挥自己的优势,但现在我不知道该如何实现

例如:

public sealed class MyTrickyClass<T> : IQueryable<T>
{
    ...
}

public MyTrickyClass<T> GetData()
{
    return repository.GetAllData();
}
公共密封类MyTrickyClass:IQueryable
{
...
}
公共MyTrickyClass GetData()
{
返回repository.GetAllData();
}
还有我的单元测试

[Test Method]
public void CanGetData()
{
    var data = (new List<Record>() { new Record() }).AsQueryable();
    var mockRepository = new Mock<IRepository<Record>>();
    mockRepository.Setup(s => s.GetAllData()).Returns(data);

    MyService service = new MyService(mockRepository.Object);
    var result = service.GetData();

    Assert.IsNotNull(result);

}
[试验方法]
公共数据
{
var data=(新列表(){new Record()}).AsQueryable();
var mockRepository=new Mock();
mockRepository.Setup(s=>s.GetAllData())。返回(数据);
MyService service=newmyservice(mockRepository.Object);
var result=service.GetData();
Assert.IsNotNull(结果);
}
这不会编译,因为GetAllData()的返回类型是
MyTrickyClass
。如果我尝试将
data
转换为
MyTrickyClass
类型,转换将失败


所有这些都是有道理的,但它让我想知道什么是正确的解决方案。对于这种情况,有哪些变通办法?我可能可以更改MyTrickyClass,但理想情况下,我希望找到一个不使用它的解决方案。

您可以使用
MyTrickyClass
实现接口
ITrickyClass
,它继承自
IQueryable
。这对你的班级本身来说似乎是微创的,而且你会有一个很好的嘲弄机会

测试中的
数据
变量是
IQueryable
,而不是
MyTrickyClass

以下是修复此问题的一些可能性:

  • 将测试中的
    数据
    更改为
    MyTrickyClass
    (尽管我猜这是否可能,您已经完成了)
  • 使MyTrickyClass更易于构建,然后执行上述操作
  • 更改
    IRepository
    的接口,使其返回一个
    IQueryable
    而不是
    MyTrickyClass
    (如果它只需要
    IQueryable
    就最好了)
  • 将存储库包装在一个层中,该层还可以包装返回值。这是另一个抽象层,但如果您发现无法更改存储库或
    MyTrickyClass
    ,那么您可能希望将自己与它隔离开来
  • 正如@Erik Dietrich所建议的,您可以让MyTrickyClass实现一个接口。但是,您仍然无法使用
    IQueryable
    创建数据,因为强制转换将失败。但是,您可以创建一个
    ITrickyClass
    的模拟,或者创建一个实现接口的小存根类(如果
    MyTrickyClass
    是一个域对象,您可能会在很多地方使用它,因此手动编码的存根可能更有用)

我猜MyService等于MyTrickyClass?不,
MyService
是具有我要测试的方法的类,
GetData
。在该方法中调用的
GetAllData()
方法返回
MyTrickyClass
对象。您仍然无法将列表中的
IQueryable
成功转换为
ITrickyClass