我的 SQL 表中有一个二进制列,我使用以下 C# 代码成功查询了该表:
var hash = "http://www.whatever.com".ToSHA256HashBytes();
var landingPage = context.LandingPages.FirstOrDefault(lp => lp.UrlHash == hash);
- 请注意:“ToSHA256HashBytes”是我编写的一个扩展方法,它返回一个 byte[]
这非常有效,因为 SQL 将比较 byte[] 的内容并返回与匹配“UrlHash”的记录。
但是,这在我的单元测试中不起作用,因为比较是在内存中执行的,并且比较 byte[] 的规则显然是不同的。如果两个字节数组位于内存中的同一位置,而不是通过比较数组的内容,C# 似乎会认为它们相等。
这意味着下面的单元测试将失败
var data = new[]
{
new LandingPage() { UrlHash = "http://www.whatever.com".ToSHA256HashBytes() },
new LandingPage() { UrlHash = "http://mycompany.com/another/folder/page.php"".ToSHA256HashBytes() },
new LandingPage() { UrlHash = "http://someothercompany.com/folder/somepage.html"".ToSHA256HashBytes() }
};
var mockData = new Mock<DbSet<T>>();
var queryableData = data.AsQueryable();
mockData.As<IQueryable<T>>().Setup(m => m.Provider).Returns(queryableData.Provider);
mockData.As<IQueryable<T>>().Setup(m => m.Expression).Returns(queryableData.Expression);
mockData.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(queryableData.ElementType);
mockData.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(queryableData.GetEnumerator());
var mockContext = new Mock<MyContext>();
mockContext.Setup(m => m.LandingPages).Returns(mockData.Object);
var hash = "http://www.whatever.com".ToSHA256HashBytes();
var landingPage = mockContext.Object.LandingPages.FirstOrDefault(lp => lp.UrlHash == hash);
Assert.IsNotNull(landingPage);
有没有一种方法可以编写 Linq 查询,以便它在单元测试和查询数据库时都可以工作?
我发现了一个非常类似的问题 https://stackoverflow.com/questions/3744031/comparing-byte-in-linq-to-sql-and-in-a-unit-test-that-uses-mocking但OP通过更改他的查询来解决他的问题(不幸的是,这对我来说不是一个选择),而不是真正找到他原来问题的解决方案。
您可以使用Enumerable.SequenceEqual http://msdn.microsoft.com/en-us/library/vstudio/bb348567(v=vs.100).aspx扩展方法:
var landingPage = context.LandingPages
.FirstOrDefault(lp => lp.UrlHash.SequenceEqual(hash));
返回值SequenceEqual
is true
当且仅当两个源序列长度相等,并且根据其类型的默认相等比较器,它们对应的元素相等。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)