簡體   English   中英

如何在 do.net 核心測試項目中使用用戶機密

[英]How to use user secrets in a dotnet core test project

我想將我的集成測試的數據庫連接字符串存儲為用戶機密。 我的 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"
}

我已將以下內容添加到測試 class 的構造函數中:

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'.

我是否遺漏了什么或者我試圖不支持的是什么?

請參閱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()

但請注意,它不允許在構建服務器上運行測試

您必須在應用程序的Startup中指定UserSecretsId。

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

然后,您必須在測試項目中使用.AddUserSecrets(Assembly assembly)的重載。 例:

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

資料來源: https//stackoverflow.com/a/40775511/5270073

我的基本測試類初始化 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
        }
    }

在我的場景中這樣做的好處是,如果開發人員分配用戶機密,則測試將在本地正確運行,而無需代表他們更改任何代碼。

此處列出的其他帖子對手動完成這一切有很大幫助,但 VS2022 已為您自動完成。

在 Visual Studio 2022 中,只需右鍵單擊測試項目名稱和 go 即可“管理用戶機密”。

如果您尚未安裝 Microsoft.Extensions.Configuration.UserSecrets,它會提示您“...需要依賴項。您想添加它們嗎...”

單擊 Yes,secrets.json 文件將打開,您就可以開始比賽了。

(如果您已經安裝了 UserSecrets,它只會打開 secrets.json。)

這是一個對我非常有用的代碼片段。

using FluentAssertions;
using Microsoft.Extensions.Configuration;
using Project.Cosmos;

namespace Project.Model.Tests;

public class CosmosDbRepository
    {
    private IConfiguration Configuration { get; }

    public CosmosDbRepository()
        {
        var builder = new ConfigurationBuilder()
            .AddUserSecrets< CosmosDbRepository >();

        Configuration = builder.Build();
        }

    [Fact]
    public async Task Should_connect_to_cosmos_db()
        {
        // Arrange
        var uri = Configuration[ "Cosmos:Uri" ];
        var key = Configuration[ "Cosmos:Key" ];
        var _repo = await CosmosRepository.CreateRepo( uri, key );
        // Act
        var account = await _repo.Client.ReadAccountAsync();
        // Assert
        account.Should().NotBeNull( "A valid connection should be able to query its account." );
        }
    }

用 secrets.json 的

{ "Cosmos": { "Uri": "你的價值在這里", "Key": "你的價值在這里" } }

對於設置,您可以使用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"]
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM