我的Web应用程序需要从appsettings.json文件中读取Document DB键。我创建了一个带有键名的类,并在ConfigureaServices()
中读取了Config部分:
public Startup(IHostingEnvironment env) {
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
public void ConfigureServices(IServiceCollection services) {
services.AddMvc().AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
services.AddSession();
Helpers.GetConfigurationSettings(services, Configuration);
DIBuilder.AddDependency(services, Configuration);
}
我正在寻找在Test项目中阅读Key值的方法。
答案 0 :(得分:39)
这是基于博客文章 Using Configuration files in .NET Core Unit Test Projects (为.NET Core 1.0编写)。
在Integration测试项目根目录中创建(或复制)appsettings.test.json,并在属性中指定" Build Action"作为内容和"复制如果更新"到输出目录。请注意,最好让文件名(例如appsettings.test.json
)与普通appsettings.json
不同,因为主项目中的文件可能会覆盖测试项目中的文件,如果相同的名称将是使用
如果尚未包含JSON配置文件NuGet包(Microsoft.Extensions.Configuration.Json),请将其包括在内。
在测试项目中创建一个方法
public static IConfiguration InitConfiguration()
{
var config = new ConfigurationBuilder()
.AddJsonFile("appsettings.test.json")
.Build();
return config;
}
照常使用配置
var config = InitConfiguration();
var clientId = config["CLIENT_ID"]
顺便说一句:您也可能有兴趣将配置读入IOptions类,如 Integration test with IOptions<> in .NET Core 中所述:
var options = config.Get<MySettings>();
答案 1 :(得分:3)
老实说,如果你是单元测试一个应用程序,你应该尝试将你正在测试的类与所有依赖项隔离开来,比如调用其他类,访问文件系统,数据库,网络等。除非你正在进行集成测试或功能测试。
话虽如此,要对应用程序进行单元测试,您可能希望从appsettings.json文件中模拟这些值,然后测试您的逻辑。
所以你的"DocumentDb": {
"Key": "key1"
}
会是这样的。
public class DocumentDbSettings
{
public string Key { get; set; }
}
然后创建一个设置类。
ConfigureServices()
然后在services.Configure<DocumentDbSettings>(Configuration.GetSection("DocumentDb"));
方法中注册。
// ...
private readonly DocumentDbSettings _settings;
public HomeController(IOptions<DocumentDbSettings> settings)
{
_settings = settings.Value;
}
// ...
public string TestMe()
{
return $"processed_{_settings.Key}";
}
然后例如你的控制器/类看起来像这样。
public class HomeControllerTests
{
[Fact]
public void TestMe_KeyShouldBeEqual_WhenKeyIsKey1()
{
// Arrange
const string expectedValue = "processed_key1";
var configMock = Substitute.For<IOptions<DocumentDbSettings>>();
configMock.Value.Returns(new DocumentDbSettings
{
Key = "key1" // Mocking the value from your config
});
var c = new HomeController(configMock);
// Act
var result = c.TestMe();
// Assert
Assert.Equal(expectedValue, result);
}
}
然后在您的测试项目中,您可以创建这样的单元测试类。
col1 col2 col3 col4
ID1 text text text...REP=(info1|info2|info3)
ID2 text text text...REP=(info1|info2|info3)
我使用NSubstitute v2.0.0-rc进行模拟。
答案 2 :(得分:2)
在您测试项目的project.json
中,添加以下依赖项:
"dependencies": {
"xunit": "2.2.0-beta2-build3300",
"Microsoft.AspNetCore.TestHost": "1.0.0",
"dotnet-test-xunit": "2.2.0-preview2-build1029",
"BancoSentencas": "1.0.0-*"
},
BancoSentencas
是我想测试的项目。其他软件包来自xUnit和TestHost,它们将是我们的内存服务器。
还包括appsettings.json的此构建选项:
"buildOptions": {
"copyToOutput": {
"include": [ "appsettings.Development.json" ]
}
}
在我的测试项目中,我有以下测试类:
public class ClasseControllerTeste : IClassFixture<TestServerFixture> {
public ClasseControllerTeste(TestServerFixture fixture) {
Fixture = fixture;
}
protected TestServerFixture Fixture { get; private set; }
[Fact]
public async void TestarRecuperarClassePorId() {
using(var client = Fixture.Client) {
var request = await Fixture.MyHttpRequestMessage(HttpMethod.Get, "/api/classe/1436");
var response = await client.SendAsync(request);
string obj = await response.Content.ReadAsStringAsync();
ClasseModel classe = JsonConvert.DeserializeObject<ClasseModel>(obj);
Assert.NotNull(classe);
Assert.Equal(1436, classe.Id);
}
}
}
我还有TestServerFixture类,它将配置内存服务器:
public class TestServerFixture : IDisposable {
private TestServer testServer;
protected TestServer TestServer {
get {
if (testServer == null)
testServer = new TestServer(new WebHostBuilder().UseEnvironment("Development").UseStartup<Startup>());
return testServer;
}
}
protected SetCookieHeaderValue Cookie { get; set; }
public HttpClient Client {
get {
return TestServer.CreateClient();
}
}
public async Task<HttpRequestMessage> MyHttpRequestMessage(HttpMethod method, string requestUri) {
...
login stuff...
...
Cookie = SetCookieHeaderValue.Parse(response.Headers.GetValues("Set-Cookie").First());
var request = new HttpRequestMessage(method, requestUri);
request.Headers.Add("Cookie", new CookieHeaderValue(Cookie.Name, Cookie.Value).ToString());
request.Headers.Accept.ParseAdd("text/xml");
request.Headers.AcceptCharset.ParseAdd("utf-8");
return request;
}
public void Dispose() {
if (testServer != null) {
testServer.Dispose();
testServer = null;
}
}
}
这就是我测试项目的方式。我使用主项目中的Startup.cs,并在我的测试项目中创建了appsettings.json的副本(appsettings.Development.json)
答案 3 :(得分:2)
按以下方式修改时,Suderson的解决方案对我有用:
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables();
IConfiguration config = builder.Build();
//Now, You can use config.GetSection(key) to get the config entries
答案 4 :(得分:1)
将appSettings.json
复制到您的测试项目根目录,并将其属性标记为内容,复制如果更新。
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables();
ConfigurationManager.Configuration = builder.Build();
ConfigurationManager
是一个类,它有一个静态属性Configuration
。这样整个应用程序就可以像ConfigurationManager.Configuration[<key>]
答案 5 :(得分:1)
我更喜欢从流而不是文件中读取配置。这样可以提供更大的灵活性,因为您可以创建轻量级的测试设置而无需提交多个json配置文件:
public static class ConfigurationHelper
{
public static IConfigurationRoot GetConfiguration()
{
byte[] byteArray = Encoding.ASCII.GetBytes("{\"Root\":{\"Section\": { ... }}");
using var stream = new MemoryStream(byteArray);
return new ConfigurationBuilder()
.AddJsonStream(stream)
.Build();
}
}
答案 6 :(得分:1)
答案 7 :(得分:0)
对于ASP.NET Core 2.x项目,将appsettings.json
文件自动复制到构建目录:
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<None Include="..\MyProj\appsettings.json" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
</Project>
答案 8 :(得分:0)
如果您使用的是WebApplicationFactory
to create a test server for integration tests,并且已经可以在服务器端控制器中获取配置值(您可能会这样做!),那么只需重复使用此命令(并在集成测试中获得您需要的任何其他注入的物品),如下所示:
// Your test fixtures would be subclasses of this
public class IntegrationTestBase : IDisposable
{
private readonly WebApplicationFactory<Startup> _factory;
protected readonly HttpClient _client;
// The same config class which would be injected into your server-side controllers
protected readonly IMyConfigService _myConfigService;
// Constructor (called by subclasses)
protected IntegrationTestBase()
{
// this can refer to the actual live Startup class!
_factory = new WebApplicationFactory<Startup>();
_client = _factory.CreateClient();
// fetch some useful objects from the injection service
_myConfigService = (IMyConfigService)_factory.Server.Host.Services.GetService(typeof(IMyConfigService));
}
public virtual void Dispose()
{
_client.Dispose();
_factory.Dispose();
}
}
请注意,在这种情况下,您无需复制appsettings.json
,您将自动使用(测试)服务器使用的同一appsettings.json
。
答案 9 :(得分:0)
添加配置文件
首先,将一个appconfig.json文件添加到集成测试项目中
配置要复制到输出的appconfig.json文件 通过更新
添加NuGet程序包
在单元测试中使用配置
[TestClass]
public class IntegrationTests
{
public IntegrationTests()
{
var config = new ConfigurationBuilder().AddJsonFile("appconfig.json").Build();
_numberOfPumps = Convert.ToInt32(config["NumberOfPumps"]);
_numberOfMessages = Convert.ToInt32(config["NumberOfMessages"]);
_databaseUrl = config["DatabaseUrlAddress"];
}
}