【问题标题】:How to use user secrets in a dotnet core test project如何在 dotnet 核心测试项目中使用用户机密
【发布时间】:2017-06-15 22:34:33
【问题描述】:

我想为我的集成测试存储一个数据库连接字符串作为用户密码。我的 project.json 看起来像这样:

{
  ...

  "dependencies": {
    ...
    "Microsoft.Extensions.Configuration.UserSecrets": "1.1.0"        
  },

  "tools": {
    "Microsoft.Extensions.SecretManager.Tools": "1.1.0-preview4-final"
  },

  "userSecretsId": "dc5b4f9c-8b0e-4b99-9813-c86ce80c39e6"
}

我已将以下内容添加到我的测试类的构造函数中:

IConfigurationBuilder configurationBuilder = new ConfigurationBuilder()
    .AddJsonFile("appsettings.json")
    .AddUserSecrets();

但是,当我运行测试时,遇到该行时会引发以下异常:

An exception of type 'System.InvalidOperationException' occurred in Microsoft.Extensions.Configuration.UserSecrets.dll but was not handled in user code

Additional information: Could not find 'UserSecretsIdAttribute' on assembly 'dotnet-test-nunit, Version=3.4.0.0, Culture=neutral, PublicKeyToken=null'.

我是否遗漏了什么或者我试图不支持的内容?

【问题讨论】:

    标签: unit-testing configuration .net-core app-secret


    【解决方案1】:

    请参阅https://patrickhuber.github.io/2017/07/26/avoid-secrets-in-dot-net-core-tests.html 中的说明,特别是在 InitialiseTest 添加中

    // the type specified here is just so the secrets library can 
                // find the UserSecretId we added in the csproj file
                var builder = new ConfigurationBuilder()
                    .AddUserSecrets<HttpClientTests>();
    
                Configuration = builder.Build()
    

    但请注意,它不允许在构建服务器上运行测试

    【讨论】:

    • 确保使用Microsoft.Extensions.Configuration.UserSecrets nuget package 才能使用AddUserSecrets 方法。
    【解决方案2】:

    您必须在应用程序的Startup 中指定 UserSecretsId。

    [assembly: UserSecretsId("xxx")]
    namespace myapp
    {
        public class Startup
        {
        ...
    

    那么你必须在你的测试项目中使用.AddUserSecrets(Assembly assembly)的重载。示例:

    .AddUserSecrets(typeof(Startup).GetTypeInfo().Assembly)
    

    来源:https://stackoverflow.com/a/40775511/5270073

    【讨论】:

      【解决方案3】:

      我的基础测试类初始化了 ConfigurationBuilder,因此知道具有 userSecretsId 的程序集更加棘手。

      但是我们可以确定一路调用的所有程序集,如下

          var builder = new ConfigurationBuilder()
              // NOTE: Make the appsettings optional since we might just have a appsettings.TestConfig
              .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
              .AddJsonFile($"appsettings.{environment}.json", optional: true)
              // NOTE: This brings in the test assembly's own settings as overrides for the base and environment values
              .AddJsonFile($"appsettings.TestConfig.json", optional: true)
              .AddEnvironmentVariables();
              
          var currentAssembly = Assembly.GetExecutingAssembly();
          var callerAssemblies = new StackTrace().GetFrames()
              .Select(x => x.GetMethod().ReflectedType.Assembly).Distinct()
              .Where(x => x.GetReferencedAssemblies().Any(y => y.FullName == currentAssembly.FullName));
      
          UserSecretsIdAttribute attribute = null;
          foreach (var assembly in callerAssemblies)
          {
              attribute = assembly.GetCustomAttribute<UserSecretsIdAttribute>();
              if (attribute != null)
              {
                  break;
              }
          }
      
          if (attribute != null)
          {
              var userSecrets = attribute.UserSecretsId;
      
              // Wire up user secrets if we have them
              if (!string.IsNullOrEmpty(userSecrets))
              {
      #if NETSTANDARD2_0
                  builder.AddUserSecrets(userSecrets);
      #else
                  builder.AddUserSecrets(userSecrets, false);
      #endif
              }
          }
      

      在我的场景中这样做的好处是,如果开发人员分配了用户密码,测试将在本地正确运行,而无需代表他们更改任何代码。

      【讨论】:

        【解决方案4】:

        对于设置,您可以使用 appsettings.json,而不是 project.json。它看起来像这样:

        {
            "userSecretsId": "dc5b4f9c-8b0e-4b99-9813-c86ce80c39e6"
        }
        

        确保通过更改 project.json 将文件复制到输出:

        "buildOptions": {
            "copyToOutput": "appsettings.json"
        }
        

        现在您可以像这样检索秘密:

        [Fact]
        public MyTest()
        {
            var appSettings = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json")
                .Build();
        
            var secret = appSettings["userSecretsId"]
        }
        

        【讨论】:

        • 这似乎只是告诉我如何在 ASP.NET 项目中使用机密,这不是我在这里所做的。我已经有一个单独的网络项目,我在其中成功使用了秘密,我要问的是一个类库测试项目。
        • 对不起,我忽略了那个,我看看有没有解决办法。
        • 这个应该可以解决问题:-)。我想你忘记了 copyToOutput。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多