【发布时间】:2013-01-18 07:52:57
【问题描述】:
我正在使用模拟的IQueryable(使用最小起订量)设置测试,我想在调用.Where() 时自行返回:
[SetUp]
public void Setup() {
mockPocos = new Mock<IQueryable<Poco>>();
mockPocos.Setup(foo => foo.Where(It.IsAny<Expression<Func<Poco, bool>>>()))
.Returns(mockPocos.Object);
}
(这样,我可以模拟.Count 之类的方法/属性,并且知道无论被测试的方法在IQueryable 上运行查询多少次,它都会返回我可以控制的值。)
这可以编译,但是当我运行它时,我得到了这个异常:
Tests.PocoTest.TestPocoQueryable:
SetUp : System.NotSupportedException : Expression references a method that does not belong to the mocked object: foo => foo.Where<Poco>(It.IsAny<Expression`1>())
我怎样才能让它工作?
编辑:作为对 cmets 的回应,这就是我想像这样使用 Moq 的原因。
在我正在测试的方法中,我有这样的代码:
public int[] MethodToTest(IQueryable<Poco> pocos, MockableDependency dependency)
{
var mostRecentUpdate = (from poco in pocos
select poco.Date_Last_Updated).Max();
var recentPocos = pocos.Where(x => x.Date_Last_Updated.CompareTo(mostRecentUpdate) >= 0);
///...snip...
result[0] = SomePrivateCalculation(recentPocos.Count);
result[1] = dependency.DoADifferentCalculation(recentPocos);
}
我已经在嘲笑MockableDependency,所以我实际上不需要担心Pocos 在pocos 中是什么。但是,我希望能够控制 recentPocos.Count 的值是什么,并且我希望能够知道无论在 .Count 之前运行了多少个查询,它都会返回相同的值 pocos被访问。
【问题讨论】:
-
看起来您不想模拟 IQueryable 而是模拟 LINQ 查询。
-
这是什么意思? (我不知道 LINQ 是如何在幕后工作的。)
-
我不确定您如何使用 Moq 模拟 LINQ 查询。我只是提醒,您想模拟函数
Where,这是 LINQ 提供的扩展方法,而不是IQueryable的一部分。 -
我觉得你玩得太过火了。您应该将您的模拟策略定位到高阶服务,并具有替换整个子系统的能力。您似乎在做的是试图在 Linq 上部分模拟单个接口方法,这甚至不是一个实现。我看不到这样做的好处。你想达到什么目的?
-
@Michael Viktor Starberg:我更新了我的问题以回应您的评论。
标签: c# testing mocking moq iqueryable