.NET – I can test the structure of Linq query in the case of unreal implementation

I heard that when testing EF, due to the differences between the LINQ to Objects and LINQ to Entities providers, you need to use integration tests for real-time DB.

Why can’t we unit test the construction of the query without actual execution? I originally thought you could attach your IQueryable to the LINQ to Entities provider in some way and confirm that the SQL was generated correctly (using ToTraceString which does not perform the actual query).

I imagine going along these lines Line of code (this query works well in L2O but does not work well in L2E):

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

testQuery.SetQueryProvider("L2E")

Assert.DoesNotThrow(testQuery.ToTraceString())
End Sub

Edit

The solution I tried to implement GertArnold is as follows:

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)

Throw ProviderIncompatibleException and display the message “An error occurred while obtaining provider information from the database. This may be caused by the incorrect connection string used by Entity Framework. Check the internal exception for details Information and make sure the connection string is correct.” This is the complete exception chain:

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

The question is: which IQueryable? The interface itself is gone. With EF, you are dealing with classes that implement IQueryable, but you have to do more than that. In fact, they are fully capable of working with context and query providers that are already connected under the hood. IQueryable.IQueryProvider is a read-only property, so it is set by the factory to create a specific IQueryable implementation.

So, your testQuery will be an ObjectQuery because it is taken from myDb and it cannot be EF Context.

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

Isn’t this your actual problem? In fact, I even want to know if you want a different query provider. I think you will want the EF query provider to do this, otherwise it is still not guaranteed to work the same as EF.

Anyway, you You can create a context with a fake database name in its connection string (to make sure it is not connected), and check the validity of ((ObjectQuery)testQuery).ToTraceString(). As long as you don’t iterate the testQuery, it doesn’t matter. I As you can imagine, this kind of test has some value when combining queries in complex execution paths. (But I would rather avoid this).

I heard that When testing EF, due to the differences between the LINQ to Objects and LINQ to Entities providers, you need to use integration testing for real-time DB.

Why can’t we perform queries without actual execution? Is the construct for unit testing? I originally thought you could attach your IQueryable to the LINQ to Entities provider in some way and confirm that the SQL was generated correctly (using ToTraceString which does not perform the actual query).

I imagine going along these lines Line of code (this query works well in L2O but does not work well in L2E):

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

testQuery.SetQueryProvider("L2E")

Assert.DoesNotThrow(testQuery.ToTraceString())
End Sub

Edit

The solution I tried to implement GertArnold is as follows:

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)

Throw ProviderIncompatibleException and display the message “An error occurred while obtaining provider information from the database. This may be caused by the incorrect connection string used by Entity Framework. Check the internal exception for details Information and make sure the connection string is correct.” This is the complete exception chain:

System.Data.ProviderIncompatibleException: An error occurred while getting provider information from the database. This can be caused by E ntity 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.

< p>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

The question is: which IQueryable? The interface itself is gone. With EF, you are dealing with classes that implement IQueryable, but you have to do more than that. In fact, they are fully capable of working with context and query providers that are already connected under the hood. IQueryable.IQueryProvider is a read-only property, so it is set by the factory to create a specific IQueryable implementation.

So, your testQuery will be an ObjectQuery because it is taken from myDb and it cannot be EF Context.

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

Isn’t this your actual problem? In fact, I even want to know if you want a different query provider. I think you will want the EF query provider to do this, otherwise it is still not guaranteed to work the same as EF.

Anyway, you You can create a context with a fake database name in its connection string (to make sure it is not connected), and check the validity of ((ObjectQuery)testQuery).ToTraceString(). As long as you don’t iterate the testQuery, it doesn’t matter. I As you can imagine, this kind of testing has some value when combining queries in complex execution paths. (But I would rather avoid this).

Leave a Comment

Your email address will not be published.