LINQ Contains语句在复杂对象上用于字符串列表

时间:2015-12-15 10:50:34

标签: c# linq moq

我是个白痴吗?这是一个Mocked存储库:

Mock<IRepository> repMock = new Mock<IRepository>();
Quote q1 = new Quote { QuoteId = 123 };
Quote q2 = new Quote { QuoteId = 345 };
repMock.Setup(m => m.GetQuotes(It.IsAny<Expression<Func<Quote, bool>>>())).Returns((new List<Quote> { q1, q2 }).AsQueryable);

这是一个LINQ语句,它将这些Id视为字符串,并获取包含字符串“3”(即两者)的那些:

Assert.AreEqual(2, repMock.Object.GetQuotes(q => q.QuoteId.ToString().Contains("3")).Count());

这是应用于获取一个字符串的相同主体 - 但这失败了。它返回两个字符串:

Assert.AreEqual(1, repMock.Object.GetQuotes(q => q.QuoteId.ToString().Contains("1")).Count());

然而,如果你将字符串拉出到他们自己的列表中并运行包含该字符串,它将按预期工作:

List<string> foo = repMock.Object.GetQuotes(q => q.QuoteId.ToString().Contains("3")).Select(q => q.QuoteId.ToString()).ToList();
Assert.AreEqual(1, foo.Where(f => f.Contains("1")).Count());

这里发生了什么?这段代码似乎实际上在生产中工作并按预期过滤字符串 - 它只在单元测试中失败?

编辑:我看到了@IvanStoev在这里所说的逻辑,我正在设置Mock以返回两个对象的列表而不管传入的函数。那么我如何才能获得测试来履行这个功能呢?

1 个答案:

答案 0 :(得分:3)

我认为问题出在这里

repMock.Setup(m => m.GetQuotes(It.IsAny<Expression<Func<Quote, bool>>>()))
    .Returns((new List<Quote> { q1, q2 }).AsQueryable);

我对模型框架不是很熟悉,但从逻辑上讲,你设置接收谓词的GetQuotes函数总是返回整个列表,忽略传递的谓词,这样&# 39;为什么你的测试代码总是返回2项。

更新:根据你的编辑,我猜你可以使用类似的东西

repMock.Setup(m => m.GetQuotes(It.IsAny<Expression<Func<Quote, bool>>>()))
    .Returns((Expression<Func<Quote, bool>> predicate) => 
        (new List<Quote> { q1, q2 }).AsQueryable().Where(predicate));