nunit-console: PlatformNotSupportedException when testing a .NET Standard assembly with reference to System.Data.SqlClient

Hello, As the title suggests we faced an issue when trying to unit test a .NET Standard assembly which transitively references System.Data.SqlClient.

Steps to reproduce:

  1. Create a .NET Standard library which uses System.Data.SqlClient 1.1 Create an empty solution and a new .NET Standard project using Visual Studio 1.2 Add a package reference to System.Data.SqlClient, version 4.6.1 in the project’s .csproj file 1.3 Create a public method which simply opens a new SqlConnection to a local database
  2. Create a .NET 6 NUnit test project 2.1 Create a .NET 6 project using visual studio 2.2 Add a package a package reference to NUnit, version 3.7.1, Microsoft.NET.Test.SDK, version 17.4.0 and NUnit3TestAdapter, version 3.15.1 2.3 Add a project reference to the the project created in 1. 2.4 Create a test method, mark it with a [Test] attribute and invoke the method from the .NET Standard library created in 1.3
  3. Build the solution
  4. (Optional if already installed)Install Nunit.TestRunner.Core as a tool with the command dotnet tool install --local "NUnit.ConsoleRunner.NetCore" --version "3.16.1-dev00002"
  5. Navigate to {project_directory}/bin/debug/net6
  6. Using powershell invoke dotnet nunit {PROJECT_NAME}.Tests.dll
  7. Observe that the tests fail with the following exception:
System.PlatformNotSupportedException : System.Data.SqlClient is not supported on this platform.
   at System.Data.SqlClient.SqlConnection..ctor(String connectionString)
   at AssemblyUnderTest.LibMethods.GetDbStrings()...

Probable cause: The .NET Standard 2.0 assembly System.Data.SqlClient which is built and located directly under /bin is simply a placeholder assembly which throws PlatformNotSupportedException in every public method that it exposes. The reason for this is that the implementation of System.Data.SqlClient is platform-specific and because of that, the runtime must locate this platform-specific implementation during the runtime of the program. This is usually not a problem, since this information is located in the {project_directory}.Tests.deps.json file, which the runtime uses to locate the concrete implementation of System.Data.SqlClient.

If we add the following lines anywhere in our test:

var loadedDeps = AppContext.GetData("APP_CONTEXT_DEPS_FILES");    
TestContext.Out.WriteLine($"LOADED DEPS:\r\n{loadedDeps}");

we can see that the output when the test is ran via Visual Studio and with the nunit console is different.

For Visual Studio it will be similar to the following:

LOADED DEPS:
C:\\Users\\USER\\source\\repos\\TestProject.Tests\\TestProject.Tests\\bin\\Debug\\net6.0\\TestProject.Tests.deps.json;
C:\\Program Files\\dotnet\\shared\\Microsoft.NETCore.App\\6.0.8\\Microsoft.NETCore.App.deps.json

For the nunit console it will be similar to:

LOADED DEPS:
C:\Users\USER\.nuget\packages\nunit.consolerunner.netcore\3.16.1-dev00002\tools\net6.0\any\nunit3-netcore-console.deps.json;
C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\6.0.8\Microsoft.AspNetCore.App.deps.json;
C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.8\Microsoft.NETCore.App.deps.json

As we can see in the second output there’s no reference to TestProject.Tests.deps.json which actually contains the information on how to load the correct version of the System.Data.SqlClient assembly during runtime

Is there a workaround around this issue?

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Comments: 15 (6 by maintainers)

Most upvoted comments

interesting.

    [Test]
    public void Test1()
    {
        var assemblyLocation = typeof(SqlConnection).Assembly.Location;
        var c = new SqlConnection();
        Assert.Pass();
    }

when targeting NUnit.Engine 3.15.2 then assemblyLocation is

C:\Code\nunit-4279-repro\TestProject1\bin\Debug\net6.0\runtimes\win\lib\net6.0\Microsoft.Data.SqlClient.dll

when targeting NUnit.Engine 3.16.2 then assemblyLocation is

C:\Code\nunit-4279-repro\TestProject1\bin\Debug\net6.0\Microsoft.Data.SqlClient.dll

You can output to nunit3 format with dotnet test as well. See https://github.com/nunit/nunit3-vs-adapter/issues/1114