Can't read app.config in C# .NET Core unit test project with ConfigurationManager

前端 未结 10 811
迷失自我
迷失自我 2020-12-15 15:13

I\'ve created a simple unit test project to read an app.config file. Target framework is Core 2.0. I also created a Core 2.0 console app, to sanity-check myself to make sure

相关标签:
10条回答
  • 2020-12-15 15:49

    .CORE 3.1 To find out what dll.config file was being used, I debugged the test by adding this line and looking to see what the value is.

    string path = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).FilePath;
    

    Then I found out resharper was using testhost.dll.config and VStest was using testhost.x86.dll.config. I needed to add the following lines to the project file.

      <Target Name="CopyCustomContent" AfterTargets="AfterBuild">
        <Copy SourceFiles="app.config" DestinationFiles="$(OutDir)\testhost.dll.config" />
        <Copy SourceFiles="app.config" DestinationFiles="$(OutDir)\testhost.x86.dll.config" />
      </Target>
    
    0 讨论(0)
  • 2020-12-15 15:52

    None of the answers given here provide a viable workaround when you're dealing with code accessing directly the static ConfigurationManager properties such as AppSettings or ConnectionStrings.

    The truth is, it is not possible at the moment. You can read through the discussion here to understand why: https://github.com/dotnet/corefx/issues/22101

    There is talk to implement the support for it here: https://github.com/Microsoft/vstest/issues/1758

    In my opinion it makes sense to support this scenario since it's been working on the .NET Framework plus System.Configuration.ConfigurationManager is a .NET Standard 2.0 library now.

    0 讨论(0)
  • 2020-12-15 15:53

    If you check the result of the call to ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

    It should tell you where the required configuration file should be while running unit tests for that assembly.

    I found that instead of having an app.config file, ConfigurationManager was looking for a testhost.dll.config file.

    This was for a project targeting netcoreapp2.1, with a reference to Microsoft.NET.Test.Sdk,NUnit 3.11 and Nunit3TestAdapter 3.12.0

    0 讨论(0)
  • 2020-12-15 15:58

    Add the configuration file

    First, add a appconfig.json file to the Integration test project

    Configure the appconfig.json file to be copied to the output directory by updating

    Add NuGet package

    • Microsoft.Extensions.Configuration.Json

    Use the configuration in your unit tests

    [TestClass]
    public class IntegrationTests
    {
    
    
        public IntegrationTests()
        {
            var config = new ConfigurationBuilder().AddJsonFile("appconfig.json").Build();
    
            _numberOfPumps = Convert.ToInt32(config["NumberOfPumps"]);
    
            _numberOfMessages = Convert.ToInt32(config["NumberOfMessages"]);
    
            _databaseUrl = config["DatabaseUrlAddress"];
        }
    } 
    
    0 讨论(0)
  • 2020-12-15 15:59

    A hacky, but working way is to copy the config to the same folder as an entry assembly, whatever it is:

    [SetUpFixture]
    public class ConfigKludge
    {
        [OneTimeSetUp]
        public void Setup() =>
            File.Copy(
                Assembly.GetExecutingAssembly().Location + ".config",
                Assembly.GetEntryAssembly().Location + ".config",
                true);
    
        [OneTimeTearDown]
        public void Teardown() =>
            File.Delete(Assembly.GetEntryAssembly().Location + ".config");
    }
    

    Apart from adding this class, the only thing to make it work is to include app.config file in test project (without any copying options). It should be copied to the output folder as <your test project name>.dll.config at the build step, because it's kind of default logic.

    Note the documentation for OneTimeSetUpAttribute:

    Summary: Identifies a method that is called once to perform setup before any child tests are run.

    Although it should work for parallel test runs for a single project, there could be obvious troubles when running two test projects simultaneously, since the config would get overwritten.

    However, it is still suitable for containerized test runs, like in Travis.

    0 讨论(0)
  • 2020-12-15 16:00

    For my mixed .NET-Core & .NET-Framework project, I added the following to the unit test global setup:

    #if NETCOREAPP
    using System.Configuration;
    using System.IO;
    using System.Reflection;
    #endif
    
    ...
    
    // In your global setup:
    #if NETCOREAPP
        string configFile = $"{Assembly.GetExecutingAssembly().Location}.config";
        string outputConfigFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).FilePath;
        File.Copy(configFile, outputConfigFile, true);
    #endif
    

    This copies the config file to the output path testhost.dll.config but should be resilient enough to account for future changes in the testing framework.

    Or you can copy to below, which amounts to the same thing:

    string outputConfigFile = Path.Combine(Path.GetDirectoryName(configFile), $"{Path.GetFileName(Assembly.GetEntryAssembly().Location)}.config");
    

    Credit to @stop-cran and @PaulHatcher's solutions, this is a combination of those two.

    0 讨论(0)
提交回复
热议问题