.net - 我可以在不实际执行的情况下测试 LINQ 查询的构造吗

标签 .net unit-testing linq-to-entities tdd

我听说在测试 EF 时,您需要对实时数据库使用集成测试,因为 LINQ to Objects 和 LINQ to Entities 提供程序之间存在差异。
为什么我们不能在不实际执行的情况下对查询的构造进行单元测试?我原以为您可以以某种方式将您的 IQueryable 附加到 LINQ to Entities 提供程序并确认 SQL 已正确生成(使用不执行实际查询的 ToTraceString 之类的东西)。
我想像这些行的代码(此查询在 L2O 中运行良好,但在 L2E 中运行良好):

    <Test()> _
    Public Sub Query_Should_Build_Against_L2E()
        Dim testQuery = From d In myDb
                        Where d.Status = CType(Status.Ready, Integer)

        testQuery.SetQueryProvider("L2E")

        Assert.DoesNotThrow(testQuery.ToTraceString())
    End Sub
编辑
我尝试按如下方式实现 GertArnold 的解决方案:
Dim context As New Context("Data Source=fakedbserver;Initial Catalog=fakedb;Persist Security Info=True;")
Dim result = context.myTable.Where(Function(d) d.Status=True)
这会引发 ProviderIncompatibleException显示消息“从数据库获取提供程序信息时发生错误。这可能是由 Entity Framework 使用不正确的连接字符串引起的。请检查内部异常以获取详细信息并确保连接字符串正确。”这是完整的异常链:

System.Data.ProviderIncompatibleException : An error occurred while getting provider information from the database. This can be caused by Entity Framework using an incorrect connection string. Check the inner exceptions for details and ensure that the connection string is correct.

System.Data.ProviderIncompatibleException : The provider did not return a ProviderManifestToken string.

System.InvalidOperationException : This operation requires a connection to the 'master' database. Unable to create a connection to the 'master' database because the original database connection has been opened and credentials have been removed from the connection string. Supply an unopened connection.

System.Data.SqlClient.SqlException : A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)

最佳答案

attach your IQueryable to the LINQ to Entities provider



问题是:哪个IQueryable ?接口(interface)本身什么都不是。使用 EF,您正在处理实现 IQueryable 的类。但除此之外还有很多。事实上,它们完全具备与上下文和已经附加在引擎盖下的查询提供程序合作的能力。 IQueryable.IQueryProvider是只读属性,因此它由创建特定 IQueryable 的工厂设置执行。

因此,您的 testQuery将是 ObjectQuery因为它取自myDb这只能是 EF 上下文。

Why can't we unit test the construction of the query without actually executing it?



这不是你的实际问题吗?事实上,我什至想知道您是否想要一个不同的查询提供程序。我认为您会希望 EF 查询提供程序具有这样的行为,否则仍然无法保证使用 EF 它的工作方式相同。

无论如何,您可以在其连接字符串中创建一个带有虚假数据库名称的上下文(以确保它不连接)并检查 ((ObjectQuery)testQuery).ToTraceString() 的有效性.只要不遍历 testQuery 就可以了.我可以想象,当查询由复杂的执行路径组成时,这样的测试会有一些值(value)。 (但我宁愿避免这种情况)。

关于.net - 我可以在不实际执行的情况下测试 LINQ 查询的构造吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11716507/

相关文章:

linq - 在 linq 查询中使用字典

c# - 具有动态列和行的 DevExpress WPF GridControl

.net - 如何使用 .Net 的 RegEx 从字符串中提取所有 {} 标记?

c# - 文本文件编码问题

unit-testing - 升级到 .NET Core 3.1 后,Moq 验证未按预期工作

python - 基于cmd模块为python3 shell编写unittest

python - 检测到一个方法是递归的而不调用它?

c# - DbContext 与 Ninject ADO.NET

c# - 在 LINQ to entities 查询的 "Select"部分使用表达式

c# - 使用 Linq to Entities 进行分组和多重排序