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

我听说在测试EF时,由于LINQ to Objects和LINQ to Entities提供程序之间的差异,您需要对实时DB使用集成测试.

为什么我们不能在没有实际执行的情况下对查询的构造进行单元测试?我原本以为你可以将你的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,并显示消息“从数据库获取提供程序信息时发生错误.这可能是由于实体框架使用不正确的连接字符串引起的.检查内部异常以获取详细信息并确保连接字符串正确.”这是完整的异常链:

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?接口本身就没有了.使用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就没关系.我可以想象,当在复杂的执行路径中组合查询时,这种测试有一些价值. (但我宁愿避免这种情况).

点赞