【发布时间】:2018-10-11 18:04:55
【问题描述】:
我正在尝试测试查询是否不区分大小写。此生产代码有效:
public ILookup<string, EEntry> GetEEntries(int batchId, List<string> employeeIds)
{
using (WithNoLock())
{
var result = from e in _entities.EEntries
where e.CPayBatchProcessId == batchId
&& (!e.Blocked.HasValue || e.Blocked.Value != true)
&& employeeIds.Contains(e.Id)
select e;
return result.ToLookup(e => e.Id, StringComparer.OrdinalIgnoreCase);
}
}
我无法让单元测试工作。我的第一次尝试失败了,因为我相信列表是IEnumerable 而不是IQueryable。但是,我在IQueryable 的尝试没有通过。该查询区分大小写,我不希望这样。这就是我所做的IQueryable:
[TestCase("abc", "ABC")]
public void EEntriesAreCaseInsensitive(string employeeId1Input, string employeeId1Output)
{
var payEntries = new List<EEntry>
{
new EEntry() {CPayBatchProcessId = 8, Id = employeeId1Input},
new EEntry() {CPayBatchProcessId = 8, Id = "123"}
}.AsQueryable();
var payEntriesDbSet = new Mock<DbSet<EEntry>>();
payEntriesDbSet.As<IQueryable<EEntry>>().Setup(x => x.Provider).Returns(payEntries.Provider);
payEntriesDbSet.As<IQueryable<EEntry>>().Setup(x => x.Expression).Returns(payEntries.Expression);
payEntriesDbSet.As<IQueryable<EEntry>>().Setup(x => x.ElementType).Returns(payEntries.ElementType);
payEntriesDbSet.As<IQueryable<EEntry>>().Setup(x => x.GetEnumerator()).Returns(payEntries.GetEnumerator);
var context = new Mock<ISomeContext>();
context.Setup(x => x.EEntries).Returns(payEntriesDbSet.Object);
var employeeIds = new List<string>() { "aBc", "dEf", "gHi" };
var repo = new EEntriesRepository(context.Object);
var payEntryRecords = repo.GetEEntries(8, employeeIds);
Assert.IsTrue(payEntryRecords.Contains(employeeId1Output));
}
我错过了什么?
注意:EEntry.Id 的 getter 返回 .ToUpper()。生产代码正确地忽略了这一点。测试代码没有。
【问题讨论】:
-
不管
.Contains()使用List实现吗?哪个返回false。更改它以匹配您的生产代码:employeeIds.Contains(employeeId1Output, StringComparer.OrdinalIgnoreCase)返回 true。 -
实际运行时,针对数据库,查询语法会转换为:
([Extent1].[id] IN ('aBc', 'dEf', 'gHi'))。这会针对不区分大小写的数据库运行。 -
我缺少的可能是查询语法不会仅仅因为它是 IQueryable 而被转换为 SQL。在单元测试期间,一切都在内存中。也许我在期待一些不可能的事情。
-
如果您返回 IEnumerable 并执行
var payEntryRecords = repo.GetEEntries(8, employeeIds).ToList();会发生什么?那么忽略大小写的.Contains重载是否有效? -
我认为它刚刚击中了我。我正在尝试测试查询中是否区分大小写,但这并不是我真正应该测试的。这就像在单元测试中测试 SQL Server 功能一样。在单元测试中,我需要做的是确保查询返回数据(考虑区分大小写),然后测试
ILookup在忽略大小写的情况下返回值。
标签: c# entity-framework linq iqueryable