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

前端 未结 10 809
迷失自我
迷失自我 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 16:05

    The ConfigurationManager API will only use the configuration of the app that is currently running. In a unit test project, this means the app.config of the test project, not the console application.

    .NET Core Applications aren't supposed to use app.config or ConfigurationManager, as it is a legacy "full framework" configuration system.

    Consider using Microsoft.Extensions.Configuration instead to read JSON, XML or INI configuration files. See this doc: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration

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

    Looking through the github issue's comments, I found a work around that can go in the msbuild file...

    <Target Name="CopyCustomContent" AfterTargets="AfterBuild">
      <Copy SourceFiles="app.config" DestinationFiles="$(OutDir)\testhost.dll.config" />
    </Target>
    

    This makes it easier to verify existing tests under .NET Core before porting the configuration data over to json configuration files.

    Edit

    If running under Resharper, the previous answer doesn't work as Resharper proxies the assembly, so you need

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

    Usually in .NET Framework projects, any App.config file was copied to the bin folder by Visual Studio, with the name of your executable (myApp.exe.config) so it could be reachable in runtime. Not anymore in .NET Standard or Core Framework. You must manually copy and set the file in the bin/debug or release folder. After that it could be get with something like:

                    string AssemblyName = System.IO.Path.GetFileName(System.Reflection.Assembly.GetEntryAssembly().GetName().CodeBase);
                AppConfig = (System.Configuration.Configuration)System.Configuration.ConfigurationManager.OpenExeConfiguration(AssemblyName);
    
    0 讨论(0)
  • 2020-12-15 16:13

    I came across the same issue with my xunit tests and solved it by using the instance of Configuration from ConfigurationManager. I put the static (normal) way it works in core, framework (but not unit tests) before I show the alternative way it works in all three:

            var appSettingValFromStatic = ConfigurationManager.AppSettings["mySetting"];
            var appSettingValFromInstance = ConfigurationManager.OpenExeConfiguration(Assembly.GetExecutingAssembly().Location).AppSettings.Settings["mySetting"].Value;
    

    And here is a similar/related issue. In case anyone needs to get a section you can do a similar thing, though the type must change in the app config:

    <configSections>
        <section name="customAppSettingsSection" type="System.Configuration.AppSettingsSection"/>
        <section name="customNameValueSectionHandlerSection" type="System.Configuration.NameValueSectionHandler"/>
    </configSections>
    
    <customAppSettingsSection>
        <add key="customKey" value="customValue" />
    </customAppSettingsSection>
    
    <customNameValueSectionHandlerSection>
        <add key="customKey" value="customValue" />
    </customNameValueSectionHandlerSection>
    

    Code to grab section:

            var valFromStatic = ((NameValueCollection)ConfigurationManager.GetSection("customNameValueSectionHandlerSection"))["customKey"];
            var valFromInstance = ((AppSettingsSection)ConfigurationManager.OpenExeConfiguration(Assembly.GetExecutingAssembly().Location).GetSection("customAppSettingsSection")).Settings["customKey"].Value;
    

    I feel like I am also crazy, and I know there are newer ways of doing config in core, but if one wants to do something cross-platform this is the only way I know how. I'd be very interested if anyone has alternatives

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