Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# app.config未加载到.Net Core MSTests项目中_C#_.net Core - Fatal编程技术网

C# app.config未加载到.Net Core MSTests项目中

C# app.config未加载到.Net Core MSTests项目中,c#,.net-core,C#,.net Core,我正在进行一个项目,我正在尝试将几个库从.NET Framework 4.5.2移植到.NET Core 2,并且在单元测试中尝试读取遗留的app.config appsettings时遇到了一些问题。为了将问题降低到最低限度,我在VS2017中创建了以下项目: 我有app.config文件: 以及UnitTest1.cs文件: 使用Microsoft.VisualStudio.TestTools.UnitTesting; 使用系统配置; 名称空间SimpleTestsUnits { [测

我正在进行一个项目,我正在尝试将几个库从.NET Framework 4.5.2移植到.NET Core 2,并且在单元测试中尝试读取遗留的app.config appsettings时遇到了一些问题。为了将问题降低到最低限度,我在VS2017中创建了以下项目:

我有app.config文件:


以及UnitTest1.cs文件:

使用Microsoft.VisualStudio.TestTools.UnitTesting;
使用系统配置;
名称空间SimpleTestsUnits
{
[测试类]
公共类UnitTest1
{
[测试方法]
配置管理器()中的公共void
{
Assert.AreEqual(“20”,ConfigurationManager.AppSettings[“TestKey”]);
}
}
}
在构建此项目时,将生成SimpleTestsUnits.dll,并使用SimpleTestsUnits.dll文件的同一文件夹中的app.config文件内容创建SimpleTestsUnits.dll.config

因此,当我使用VS2017运行单元测试时,“TestKey”的值总是空的,如果我调试到ConfigurationManager.AppSettings中,那里没有加载密钥

引发异常: 'Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException' 在Microsoft.VisualStudio.TestPlatform.TestFramework.dll中存在异常 类型 'Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException' 发生在Microsoft.VisualStudio.TestPlatform.TestFramework.dll中,但 未在用户代码Assert.AreEqual中处理失败。预期:。 实际值:


我错过了什么?这不应该起作用吗?

执行测试时,条目程序集不是包含测试的程序集。您可以通过在测试中添加以下行并对其进行调试来检查它:

var configLocation=Assembly.GetEntryAssembly().Location

在我的例子中,
configLocation
c:\Users\myusername\.nuget\packages\microsoft.testplatform.testhost\15.3.0-preview-20170628-02\lib\netstandard1.5\testhost.dll

因此
ConfigurationManager
希望在指定目录中的
testhost.dll.config
中找到
app.config
。我已经将它复制到这个位置,测试通过了ok(在稍微修改配置后,见下文)

另一个问题是app.config不完全正确
configSections
元素应该是
根目录中的第一个元素。所以只要删除
configSections
元素,因为它是空的,或者按照以下方式调整
app.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
  </configSections>
  <appSettings>
    <add key="TestKey" value="20" />
  </appSettings>
</configuration>
但不幸的是,这种方法需要修改测试中的代码。

MSTest以“testhost.dll”运行,这意味着ConfigurationManager在.NET core下执行时正在从“testhost.dll.config”读取设置。它将在“testhost.dll”所在的位置查找“testhost.dll.config”,但也会在您拥有测试dll的位置查找“testhost.dll.config”

因此,将资源管理器中的配置文件复制或重命名为“testhost.dll.config”将解决此问题

通过将以下MSBuild步骤添加到MSTest.csproj文件末尾的“Project”标记中,可以轻松地实现自动化



来源:()

你可以试试这个类的大小

public static class AppConfig
{
    const string Filename = "app.config";

    static readonly Configuration Configuration;

    static AppConfig()
    {
        try
        {
            Configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            if (!Configuration.HasFile)
                throw new ConfigurationErrorsException();
        }
        catch
        {
            try
            {
                var configmap = new ExeConfigurationFileMap
                {
                    ExeConfigFilename = Filename
                };

                Configuration = ConfigurationManager.OpenMappedExeConfiguration(configmap, ConfigurationUserLevel.None);
            }
            catch
            {
            }
        }
    }

    public static string Get(string key, string @default = "")
    {
        return Configuration?.AppSettings?.Settings[key]?.Value ?? @default;
    }
}

将此答案标记为问题修复程序,但是否有一种方法可以在不更改代码的情况下实现此功能?真正的问题是,我要移植到.net core的库在测试执行期间使用ConfigurationManager来获取配置,使用这种方法,我肯定需要更改它的代码。对我来说不起作用。。。在我的例子中,它所查找的位置是“C:\Users\x\.nuget\packages\microsoft.testplatform.testhost\15.5.0\lib\netstandard1.5\testhost.dll.config”,而不是“C:\Users\x\.nuget\packages\microsoft.testplatform.testhost\15.5.0\lib\netstandard1.5\testhost.dll.config”中的“$(输出路径)”实际上存在,它可能更喜欢读取该文件。但是,如果您可以删除“C:\Users\x\.nuget\packages\microsoft.testplatform.testhost\15.5.0\lib\netstandard1.5\testhost.dll.config”文件,它可能会在您的输出路径中使用testhost.dll.config文件。这应该是可以接受的答案,无需修改即可工作。如果它不适合您,请在
之前添加一个
,并在输入测试方法时检查
Assembly.GetEntryAssembly().Location
,查看是否有任何环境变量提示该位置,然后使用该变量而不是
$(OutputPath)
<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>
public static class AppConfig
{
    const string Filename = "app.config";

    static readonly Configuration Configuration;

    static AppConfig()
    {
        try
        {
            Configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            if (!Configuration.HasFile)
                throw new ConfigurationErrorsException();
        }
        catch
        {
            try
            {
                var configmap = new ExeConfigurationFileMap
                {
                    ExeConfigFilename = Filename
                };

                Configuration = ConfigurationManager.OpenMappedExeConfiguration(configmap, ConfigurationUserLevel.None);
            }
            catch
            {
            }
        }
    }

    public static string Get(string key, string @default = "")
    {
        return Configuration?.AppSettings?.Settings[key]?.Value ?? @default;
    }
}