用于单元测试我无法轻松创建的返回类型的选项
我需要对一个方法进行单元测试,该方法返回一个我无法轻易伪造或实例化的类型。该类型实现了 IQueryable
我最初认为我可以利用它来发挥我的优势,但目前我不知道如何使用。
例如:
public sealed class MyTrickyClass<T> : IQueryable<T>
{
...
}
public MyTrickyClass<T> GetData()
{
return 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);
}
这不会编译,因为 GetAllData() 的返回类型是 MyTrickyClass
。如果我尝试将 data
转换为 MyTrickyClass
类型,则转换会失败。
所有这些都是有道理的,但这让我想知道正确的解决方案是什么。对于这种情况有哪些解决方法?我也许可以更改 MyTrickyClass,但理想情况下我想找到一个不影响它的解决方案。
I need to unit test a method that returns a type I can't easily fake or instantiate. The type implements IQueryable<T>
which I originally thought I could use to my advantage, but I don't see how at this point.
For example:
public sealed class MyTrickyClass<T> : IQueryable<T>
{
...
}
public MyTrickyClass<T> GetData()
{
return repository.GetAllData();
}
and my unit test
[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);
}
This won't compile because the return type of GetAllData() is MyTrickyClass<T>
. If I try to cast data
to a MyTrickyClass<Record>
type, the cast fails.
All this makes sense, but it leaves me wondering what the right solution is. What are some workarounds for this kind of situation? I may be able to change the MyTrickyClass, but ideally I'd like to find a solution that leaves it alone.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以让
MyTrickyClass
实现接口ITrickyClass
,它继承自IQueryable
。这对你的类本身来说似乎是微乎其微的,而且你有一个很好的嘲笑接缝。You could have
MyTrickyClass<T>
implement interfaceITrickyClass<T>
, which inherits fromIQueryable<T>
. That seems minimally invasive to your class itself, and you'd have a good seam for mocking.测试中的
data
变量是IQueryable
,而不是MyTrickyClass
。以下是修复它的一些可能性:
data
更改为MyTrickyClass
(尽管我猜测这是否可能,您已经完成了它)MyTrickyClass
更容易构造,然后执行上述操作IRepository
的接口,以便它返回一个IQueryable
而不是MyTrickyClass
(如果它所需要的只是IQueryable
的话,这是最好的)IQueryable
创建数据,因为转换将会失败。不过,您可以创建一个ITrickyClass
的模拟,或者创建一个实现该接口的小存根类(如果MyTrickyClass
是一个域对象,您可能会使用它无论如何,在很多地方,所以手工编码的存根可能更有用)。Your
data
variable in the test is anIQueryable<Record>
, not aMyTrickyClass<Record>
.Here are some possibilities for fixing it:
data
in the test to be aMyTrickyClass<Record>
(though I'm guessing if this was possible you'd already have done it)MyTrickyClass
easier to construct, then do the aboveIRepository
so that it returns anIQueryable
instead of aMyTrickyClass
(which is best if all it needs is theIQueryable
anyway)MyTrickyClass
then you probably want to be isolating yourself from it anywayIQueryable
as the cast will fail. You could create a mock ofITrickyClass
instead, though, or create a little stub class that implements the interface (ifMyTrickyClass
is a domain object, you'll probably be using it in a lot of places anyway, so a hand-coded stub may be more useful).