Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

app.config not beeing loaded in .Net Core MSTests project

Tags:

c#

.net-core

I'm working on a project were I'm trying to port several libraries from .NET Framework 4.5.2 to .NET Core 2, and I'm facing some problems trying to read legacy app.config appsettings in unit tests. To reduce the problem to a bare minimum reproduction scenario I've created the following project in VS2017:

enter image description here

I have the app.config file:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="TestKey" value="20" />
  </appSettings>
  <configSections>
  </configSections>
</configuration>

And the UnitTest1.cs file:

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Configuration;

namespace SimpleTestsUnits
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void FromConfigurationManager()
        {
            Assert.AreEqual("20", ConfigurationManager.AppSettings["TestKey"]);
        }
    }
}

And upon building this project the SimpleTestsUnits.dll is generated and the SimpleTestsUnits.dll.config is created with the content of the app.config file in the same folder of the SimpleTestsUnits.dll file.

So, when I run the unit test using VS2017 the value of "TestKey" is always null and if I debug into the ConfigurationManager.AppSettings there is no key loaded there.

Exception thrown: 'Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException' in Microsoft.VisualStudio.TestPlatform.TestFramework.dll An exception of type 'Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException' occurred in Microsoft.VisualStudio.TestPlatform.TestFramework.dll but was not handled in user code Assert.AreEqual failed. Expected:<20>. Actual:<(null)>.

What am I missing here? Shouldn't this be working?

like image 716
aflopes Avatar asked Dec 11 '17 11:12

aflopes


People also ask

Does MSTest work with .NET core?

In this article, I will explain about the unit test in asp.net core using MSTest. There are three different test frameworks which are supported by the unit test with asp.net core: MSTest, xUnit, and NUnit, which allow us to test our code in a consistent way.

Is app config used in .NET core?

Application configuration in ASP.NET Core is performed using one or more configuration providers. Configuration providers read configuration data from key-value pairs using a variety of configuration sources: Settings files, such as appsettings.

How do you add MSTest to a project?

On the Create a new project page, type unit test into the search box. Select the project template for the test framework that you want to use, for example MSTest Test Project or NUnit Test Project, and then select Next. On the Configure your new project page, enter a name for your project, and then select Create.


2 Answers

MSTest is running as "testhost.dll", which means that ConfigurationManager is reading settings from "testhost.dll.config" when executing under .NET core. It will look for "testhost.dll.config" where the "testhost.dll" is located but it will also also look for "testhost.dll.config" in the location where you have your test dlls.

So copying or renaming your config file in explorer to "testhost.dll.config" will solve the problem.

You can easily automate this by adding the following MSBuild step to the end of the MSTest .csproj file, within the "Project" tag.

<Target Name="CopyAppConfig" AfterTargets="Build" DependsOnTargets="Build">
    <CreateItem Include="$(OutputPath)$(AssemblyName).dll.config">
         <Output TaskParameter="Include" ItemName="FilesToCopy"/>
    </CreateItem>
    <Copy SourceFiles="@(FilesToCopy)" DestinationFiles="$(OutputPath)testhost.dll.config" />
</Target>

Source: (https://github.com/Microsoft/testfx/issues/348#issuecomment-454347131)

like image 198
Oskar Sjöberg Avatar answered Oct 18 '22 20:10

Oskar Sjöberg


When you execute the tests, the entry assembly is not an assembly with your tests. You can check it by adding following line to your test and debugging it:

var configLocation = Assembly.GetEntryAssembly().Location;

In my case configLocation was c:\Users\myusername\.nuget\packages\microsoft.testplatform.testhost\15.3.0-preview-20170628-02\lib\netstandard1.5\testhost.dll

So ConfigurationManager expects to find app.config at testhost.dll.config in specified directory. I've copied it to this location and the test passed ok (after slight modification of the config, see below).

Another problem is that your app.config is not fully correct. configSections element should be the first in <configuration> root. So just remove configSections element as it's empty or adjust your app.config in the following way:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
  </configSections>
  <appSettings>
    <add key="TestKey" value="20" />
  </appSettings>
</configuration>

Of course, it's a bad way to place config file near testhost.dll. You could change the path from which ConfigurationManager loads application config with ConfigurationManager.OpenExeConfiguration call:

[TestMethod]
public void UnitTest1()
{
    //  Put your Test assembly name here
    Configuration configuration = ConfigurationManager.OpenExeConfiguration(@"SimpleTestsUnits.dll");

    Assert.AreEqual("20", configuration.AppSettings.Settings["TestKey"].Value);
}

But unfortunately this approach requires modification of your code under test.

like image 18
CodeFuller Avatar answered Oct 18 '22 20:10

CodeFuller