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以返回两个对象的列表而不管传入的函数。那么我如何才能获得测试来履行这个功能呢?答案 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));