代码之家  ›  专栏  ›  技术社区  ›  Yves Rochon

可以从启动设置中创建配置文件。运行单元测试时是否加载json文件?

  •  4
  • Yves Rochon  · 技术社区  · 6 年前

    我作为ASP的一部分运行单元测试。NET核心MVC解决方案。的版本。确切地说,净核心是2.1。

    我在launchSettings中创建了一个配置文件部分。json文件,其中包含我希望由测试运行程序加载和注入的环境变量,以便环境变量可用,并且在运行单元测试时可以包含特定值。

    启动设置。json来自我的ASP。将my-NET属性添加为“复制到核心”文件夹,将my-NET属性添加为“复制到无”,将“复制到测试单元”属性添加为“复制到无”。

    该文件被复制到我的输出文件夹,但我不确定如何让测试运行程序将该文件与UnitTesting配置文件一起使用。我试过用“Test”这个词作为配置文件名,但似乎没有任何效果。

    下面是一个示例launchSettings。json文件:

    {
      "iisSettings": {
        "windowsAuthentication": false,
        "anonymousAuthentication": true,
        "iisExpress": {
          "applicationUrl": "http://localhost:62267/",
          "sslPort": 0
        }
      },
      "profiles": {
        "IIS Express": {
          "commandName": "IISExpress",
          "launchBrowser": true,
          "environmentVariables": {
            "ASPNETCORE_ENVIRONMENT": "Development",
            "MigrationHistoryTableName": "MigrationHistory",
            "ConnectionStringName": "EFConnectionString",
            "Redis__SSL": "True",
            "Redis__Port": "6380",
            "Redis__InstanceName": "RedisDev",
            "Redis__AbortConnect": "False",
            "Redis__ConnectionString": "{URI}:{Port},password={Password},ssl={SSL},abortConnect={AbortConnect}"
          }
        },
        "MyDataServices": {
          "commandName": "Project",
          "launchBrowser": true,
          "environmentVariables": {
            "ASPNETCORE_ENVIRONMENT": "Development",
            "MigrationHistoryTableName": "MigrationHistory",
            "ConnectionStringName": "EFConnectionString",
            "Redis__SSL": "True",
            "Redis__Port": "6380",
            "Redis__InstanceName": "RedisDev",
            "Redis__AbortConnect": "False",
            "Redis__ConnectionString": "{URI}:{Port},password={Password},ssl={SSL},abortConnect={AbortConnect}"
          },
          "applicationUrl": "http://localhost:4080/"
        },
        "UnitTesting": {
          "commandName": "Executable",
          "executablePath": "test",
          "environmentVariables": {
            "ASPNETCORE_ENVIRONMENT": "Development",
            "MigrationHistoryTableName": "MigrationHistory",
            "ConnectionStringName": "EFConnectionString",
            "Redis__SSL": "True",
            "Redis__Port": "6380",
            "Redis__InstanceName": "RedisDev",
            "Redis__AbortConnect": "False",
            "Redis__ConnectionString": "{URI}:{Port},password={Password},ssl={SSL},abortConnect={AbortConnect}"
          }
        }
      }
    }
    

    我理解默认情况下启动设置。json文件在git中被忽略。我们将使用该文件的开发版本签入代码,该版本将包含一个在开发环境中预期可用的设置示例。

    感谢您抽出时间阅读本文并提供帮助!

    2 回复  |  直到 6 年前
        1
  •  1
  •   Yves Rochon    6 年前

    我现在写了这个静态加载程序,但这并不理想:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    
    namespace MyNamespaceHere.Services.Common.Utilities
    {
        public static class LaunchSettingsLoader
        {
            public static void LaunchSettingsFixture(string launchSettingsPath = "Properties\\launchSettings.json", string profileName = "UnitTesting")
            {
                using (var file = File.OpenText(launchSettingsPath))
                {
                    var reader = new JsonTextReader(file);
                    var jObject = JObject.Load(reader);
    
                    var allprofiles = jObject
                        .GetValue("profiles", StringComparison.OrdinalIgnoreCase);
    
                    // ideally we use this
                    var variables = jObject
                        .GetValue("profiles", StringComparison.OrdinalIgnoreCase)
                        //select a proper profile here
                        .SelectMany(profiles => profiles.Children())
                        //.Where(p => p.Value<String> == profileName)
                        .SelectMany(profile => profile.Children<JProperty>())
                        .Where(prop => prop.Name == "environmentVariables")
                        .SelectMany(prop => prop.Value.Children<JProperty>())
                        .ToList();
    
                    Console.WriteLine(variables?.Count);
    
                    var profilesDictJToken = allprofiles.ToObject<Dictionary<string, JToken>>();
                    var unitTestingProfile = profilesDictJToken[profileName];
                    var unitTestingProfileDictJToken = unitTestingProfile.ToObject<Dictionary<string, JToken>>();
                    var environmentVariables = unitTestingProfileDictJToken["environmentVariables"];
                    var environmentVariablesList = environmentVariables.ToList();
    
                    foreach (var variable in environmentVariablesList)
                    {
                        var name = ((JProperty)variable).Name;
                        var value = ((JProperty)variable).Value.ToString();
                        Environment.SetEnvironmentVariable(name, value);
                    }
                }
            }
        }
    }
    
        2
  •  1
  •   Daniel Reis    3 年前

    在单元测试中使用环境变量的另一个解决方案是通过 “.runsettings” 为平台提供的文件:

    请参阅下面的链接:

    https://stackoverflow.com/a/68531200/4593944

        3
  •  0
  •   andygjp    6 年前

    我已经创建了一个软件包,可能可以帮助您: https://www.nuget.org/packages/DotNet.Project.LaunchSettings

    你可以在这里找到来源: https://github.com/andygjp/DotNet.Project.LaunchSettings

    我有一个与您类似的用例——我想测试不同的环境,并在launchSettings中保留这些环境的登录详细信息。json。

    我就是这样使用它的:

    async Task Example()
    {
      var launchSettings = VisualStudioLaunchSettings.FromCaller();
      var profiles = launchSettings.GetProfiles();
      var profile = profiles.FirstOrEmpty();
    
      var client = await AppEnvironment.FromEnvironment(profile.EnvironmentVariables).CreateClient();
      // use the client
    }
    

    它假设启动设置。json通常位于以下位置:

    我的项目->房地产->启动设置。json

    但是,如果您觉得有用,我可以添加从指定文件路径加载启动设置的功能。

    上面的示例使用它找到的第一个配置文件,但是,您也可以使用特定的配置文件。

    希望有帮助。