如何模拟LINQ to Entities助手,例如’SqlFunctions.StringConvert()’
我正在使用EF 4,并尝试使用Moq对以下行进行unit testing:
var convertError = models .Where(x => SqlFunctions.StringConvert((decimal?) (x.convert ?? 0)) == "0") .Any();
并且看起来SqlFunctions.StringConvert()
会在检测到上下文被SqlFunctions.StringConvert()
时抛出。
它给出了一个错误说:
只能从LINQ到实体调用此函数
是否有可能告诉SqlFunctions.StringConvert
返回一个模拟对象,以便我可以摆脱这个错误?
不可能因为函数的实现如下:
[EdmFunction("SqlServer", "STR")] public static string StringConvert(decimal? number, int? length) { throw EntityUtil.NotSupported(Strings.ELinq_EdmFunctionDirectCall); }
你不能使用Moq伪造这个function。 你需要更强大的模拟框架,它允许你替换静态函数调用 – 可能是Microsoft Fakes,TypeMock Isolator或JustMock。
或者你需要考虑你的测试方法,因为模仿上下文是错误的想法。 你应该改为:
var convertError = myQueryProvider.ConvertQuery(x.convert);
其中queryProvider
将是隐藏查询的可模拟类型。 查询是与数据库相关的逻辑,应该针对真实数据库进行测试。 您的查询周围的代码是您的应用程序逻辑,它应该是unit testing – 正确测试它们的最佳解决方案只是通过某个接口(在这种情况下查询提供程序,但人们经常使用完整的特定存储库)将它们分开。 这个原则来自于关注点的分离 – 查询执行是一个单独的问题,因此它被放置在自己的方法中,该方法是单独测试的。
我所做的是提供我自己的DbFunction实现,使得unit testing中的LINQ To Objects使用简单的.NET实现,而LINQ To EF在运行时使用DbFunctionAttribute,方式与System.Data.Entity.DbFunctions相同。 我曾想过嘲笑DbFunctions但是,LINQ to Objects实现很有用并且工作正常。 这是一个例子:
public static class DbFunctions { [DbFunction("Edm", "AddMinutes")] public static TimeSpan? AddMinutes(TimeSpan? timeValue, int? addValue) { return timeValue == null ? (TimeSpan?)null : timeValue.Value.Add(new TimeSpan(0, addValue.Value, 0)); } }
你可以模拟EdmFunctions,我使用NSubstitute(它也不支持模拟静态函数)完成了这个。 诀窍是将DbContext包装在一个接口中。 然后,将静态EdmFunction函数添加到静态类,并在静态类中为您的上下文创建扩展方法以调用该方法。 例如
public static class EdmxExtensions { [EdmFunction("SqlServer", "STR")] public static string StringConvert(decimal? number, int? length) { throw EntityUtil.NotSupported(Strings.ELinq_EdmFunctionDirectCall); } public static IQueryable MyFunction(this IDbContext context, decimal? number, int? length) { context.Person.Where(s => StringConvert(s.personId, number, length); }
然后,您将能够模拟MyFunction,因为它是一个可用于接口的方法,并且当您尝试调用它时,EntityFramework不会生气。
我没有尝试过Moq,但你可以用类似的方式做到这一点。
另一种方法是您可以编写自己的方法,该方法具有相同的属性标记和方法签名,然后实际实现方法unit testing目的而不是抛出exception。 entity framework忽略了函数中的代码,因此它永远不会调用它。
上述就是C#学习教程:如何模拟LINQ to Entities助手,例如’SqlFunctions.StringConvert()’分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/954368.html