[英]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)
我的基本測試類初始化 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.