- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
.NET Core 配置允许使用很多选项来添加值(环境变量、json 文件、命令行参数)。
我只是无法弄清楚并找到如何通过代码填充它的答案。
我正在为配置的扩展方法编写单元测试,我认为通过代码将其填充到单元测试中比为每个测试加载专用的 json 文件更容易。
我当前的代码:
[Fact]
public void Test_IsConfigured_Positive()
{
// test against this configuration
IConfiguration config = new ConfigurationBuilder()
// how to populate it via code
.Build();
// the extension method to test
Assert.True(config.IsConfigured());
}
更新:
一个特殊情况是“空部分”,在 json 中看起来像这样。
{
"MySection": {
// the existence of the section activates something triggering IsConfigured to be true but does not overwrite any default value
}
}
<小时/>
更新2:
正如 Matthew 在评论中指出的那样,json 中包含空部分与根本没有该部分的结果相同。我提炼了一个例子,是的,就是这样。我错误地期待着不同的行为。
那么我该怎么做以及我期望什么:
我正在为 IConfiguration 的 2 个扩展方法编写单元测试(实际上是因为 Get...Settings 方法中的值绑定(bind)由于某种原因不起作用(但那是另一个主题)。它们看起来像这样:
public static bool IsService1Configured(this IConfiguration configuration)
{
return configuration.GetSection("Service1").Exists();
}
public static MyService1Settings GetService1Settings(this IConfiguration configuration)
{
if (!configuration.IsService1Configured()) return null;
MyService1Settings settings = new MyService1Settings();
configuration.Bind("Service1", settings);
return settings;
}
我的误解是,如果我在应用程序设置中放置一个空部分,IsService1Configured()
方法将返回 true
(现在这显然是错误的)。我期望的不同之处在于,现在 GetService1Settings()
方法返回 null
为空部分,而不是像我期望的那样返回具有所有默认值的 MyService1Settings
.
幸运的是,这仍然对我有用,因为我不会有空的部分(或者现在知道我必须避免这些情况)。这只是我在编写单元测试时遇到的一个理论案例。
进一步发展(对于那些感兴趣的人)。
我用它来做什么?基于配置的服务激活/停用。
我有一个应用程序,其中编译了一个服务/一些服务。根据部署,我需要完全激活/停用服务。这是因为某些(本地或测试设置)无法完全访问完整的基础设施(缓存、指标等帮助服务)。我通过应用程序设置来做到这一点。如果服务已配置(配置部分存在),则会添加该服务。如果配置部分不存在,则不会使用它。
<小时/>精简示例的完整代码如下。
Service1
和 Service2
部分来激活/停用服务using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
namespace WebApplication1
{
public class MyService1Settings
{
public int? Value1 { get; set; }
public int Value2 { get; set; }
public int Value3 { get; set; } = -1;
}
public static class Service1Extensions
{
public static bool IsService1Configured(this IConfiguration configuration)
{
return configuration.GetSection("Service1").Exists();
}
public static MyService1Settings GetService1Settings(this IConfiguration configuration)
{
if (!configuration.IsService1Configured()) return null;
MyService1Settings settings = new MyService1Settings();
configuration.Bind("Service1", settings);
return settings;
}
public static IServiceCollection AddService1(this IServiceCollection services, IConfiguration configuration, ILogger logger)
{
MyService1Settings settings = configuration.GetService1Settings();
if (settings == null) throw new Exception("loaded MyService1Settings are null (did you forget to check IsConfigured in Startup.ConfigureServices?) ");
logger.LogAsJson(settings, "MyServiceSettings1: ");
// do what ever needs to be done
return services;
}
public static IApplicationBuilder UseService1(this IApplicationBuilder app, IConfiguration configuration, ILogger logger)
{
// do what ever needs to be done
return app;
}
}
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureLogging
(
builder =>
{
builder.AddDebug();
builder.AddConsole();
}
)
.UseStartup<Startup>();
}
public class Startup
{
public IConfiguration Configuration { get; }
public ILogger<Startup> Logger { get; }
public Startup(IConfiguration configuration, ILoggerFactory loggerFactory)
{
Configuration = configuration;
Logger = loggerFactory.CreateLogger<Startup>();
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// flavour 1: needs check(s) in Startup method(s) or will raise an exception
if (Configuration.IsService1Configured()) {
Logger.LogInformation("service 1 is activated and added");
services.AddService1(Configuration, Logger);
} else
Logger.LogInformation("service 1 is deactivated and not added");
// flavour 2: checks are done in the extension methods and no Startup cluttering
services.AddOptionalService2(Configuration, Logger);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment()) app.UseDeveloperExceptionPage();
// flavour 1: needs check(s) in Startup method(s) or will raise an exception
if (Configuration.IsService1Configured()) {
Logger.LogInformation("service 1 is activated and used");
app.UseService1(Configuration, Logger); }
else
Logger.LogInformation("service 1 is deactivated and not used");
// flavour 2: checks are done in the extension methods and no Startup cluttering
app.UseOptionalService2(Configuration, Logger);
app.UseMvc();
}
}
public class MyService2Settings
{
public int? Value1 { get; set; }
public int Value2 { get; set; }
public int Value3 { get; set; } = -1;
}
public static class Service2Extensions
{
public static bool IsService2Configured(this IConfiguration configuration)
{
return configuration.GetSection("Service2").Exists();
}
public static MyService2Settings GetService2Settings(this IConfiguration configuration)
{
if (!configuration.IsService2Configured()) return null;
MyService2Settings settings = new MyService2Settings();
configuration.Bind("Service2", settings);
return settings;
}
public static IServiceCollection AddOptionalService2(this IServiceCollection services, IConfiguration configuration, ILogger logger)
{
if (!configuration.IsService2Configured())
{
logger.LogInformation("service 2 is deactivated and not added");
return services;
}
logger.LogInformation("service 2 is activated and added");
MyService2Settings settings = configuration.GetService2Settings();
if (settings == null) throw new Exception("some settings loading bug occured");
logger.LogAsJson(settings, "MyService2Settings: ");
// do what ever needs to be done
return services;
}
public static IApplicationBuilder UseOptionalService2(this IApplicationBuilder app, IConfiguration configuration, ILogger logger)
{
if (!configuration.IsService2Configured())
{
logger.LogInformation("service 2 is deactivated and not used");
return app;
}
logger.LogInformation("service 2 is activated and used");
// do what ever needs to be done
return app;
}
}
public static class LoggerExtensions
{
public static void LogAsJson(this ILogger logger, object obj, string prefix = null)
{
logger.LogInformation(prefix ?? string.Empty) + ((obj == null) ? "null" : JsonConvert.SerializeObject(obj, Formatting.Indented)));
}
}
}
最佳答案
您可以使用MemoryConfigurationBuilderExtensions
通过字典提供它。
using Microsoft.Extensions.Configuration;
var myConfiguration = new Dictionary<string, string>
{
{"Key1", "Value1"},
{"Nested:Key1", "NestedValue1"},
{"Nested:Key2", "NestedValue2"}
};
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(myConfiguration)
.Build();
等效的 JSON 为:
{
"Key1": "Value1",
"Nested": {
"Key1": "NestedValue1",
"Key2": "NestedValue2"
}
}
等效的环境变量是(假设没有前缀/不区分大小写):
Key1=Value1
Nested__Key1=NestedValue1
Nested__Key2=NestedValue2
等效的命令行参数是:
dotnet myapp.dll \
-- \
--Key1=Value1 \
--Nested:Key1=NestedValue1 \
--Nested:Key2=NestedValue2
关于asp.net-core - 填充 IConfiguration 以进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55497800/
我获得了一些源代码示例,我想测试一些功能。不幸的是,我在执行程序时遇到问题: 11:41:31 [linqus@ottsrvafq1 example]$ javac -g test/test.jav
我想测试ggplot生成的两个图是否相同。一种选择是在绘图对象上使用all.equal,但我宁愿进行更艰巨的测试以确保它们相同,这似乎是identical()为我提供的东西。 但是,当我测试使用相同d
我确实使用 JUnit5 执行我的 Maven 测试,其中所有测试类都有 @ExtendWith({ProcessExtension.class}) 注释。如果是这种情况,此扩展必须根据特殊逻辑使测试
在开始使用 Node.js 开发有用的东西之前,您的流程是什么?您是否在 VowJS、Expresso 上创建测试?你使用 Selenium 测试吗?什么时候? 我有兴趣获得一个很好的工作流程来开发我
这个问题已经有答案了: What is a NullPointerException, and how do I fix it? (12 个回答) 已关闭 3 年前。 基于示例here ,我尝试为我的
我正在考虑测试一些 Vue.js 组件,作为 Laravel 应用程序的一部分。所以,我有一个在 Blade 模板中使用并生成 GET 的组件。在 mounted 期间请求生命周期钩子(Hook)。假
考虑以下程序: #include struct Test { int a; }; int main() { Test t=Test(); std::cout<
我目前的立场是:如果我使用 web 测试(在我的例子中可能是通过 VS.NET'08 测试工具和 WatiN)以及代码覆盖率和广泛的数据来彻底测试我的 ASP.NET 应用程序,我应该不需要编写单独的
我正在使用 C#、.NET 4.7 我有 3 个字符串,即。 [test.1, test.10, test.2] 我需要对它们进行排序以获得: test.1 test.2 test.10 我可能会得到
我有一个 ID 为“rv_list”的 RecyclerView。单击任何 RecyclerView 项目时,每个项目内都有一个可见的 id 为“star”的 View 。 我想用 expresso
我正在使用 Jest 和模拟器测试 Firebase 函数,尽管这些测试可能来自竞争条件。所谓 flakey,我的意思是有时它们会通过,有时不会,即使在同一台机器上也是如此。 测试和函数是用 Type
我在测试我与 typeahead.js ( https://github.com/angular-ui/bootstrap/blob/master/src/typeahead/typeahead.js
我正在尝试使用 Teamcity 自动运行测试,但似乎当代理编译项目时,它没有正确完成,因为当我运行运行测试之类的命令时,我收到以下错误: fatal error: 'Pushwoosh/PushNo
这是我第一次玩 cucumber ,还创建了一个测试和 API 的套件。我的问题是在测试 API 时是否需要运行它? 例如我脑子里有这个, 启动 express 服务器作为后台任务 然后当它启动时(我
我有我的主要应用程序项目,然后是我的测试的第二个项目。将所有类型的测试存储在该测试项目中是一种好的做法,还是应该将一些测试驻留在主应用程序项目中? 我应该在我的主项目中保留 POJO JUnit(测试
我正在努力弄清楚如何实现这个计数。模型是用户、测试、等级 用户 has_many 测试,测试 has_many 成绩。 每个等级都有一个计算分数(strong_pass、pass、fail、stron
我正在尝试测试一些涉及 OkHttp3 的下载代码,但不幸失败了。目标:测试 下载图像文件并验证其是否有效。平台:安卓。此代码可在生产环境中运行,但测试代码没有任何意义。 产品代码 class Fil
当我想为 iOS 运行 UI 测试时,我收到以下消息: SetUp : System.Exception : Unable to determine simulator version for X 堆
我正在使用 Firebase Remote Config 在 iOS 上设置 A/B 测试。 一切都已设置完毕,我正在 iOS 应用程序中读取服务器端默认值。 但是在多个模拟器上尝试,它们都读取了默认
[已编辑]:我已经用 promise 方式更改了我的代码。 我正在写 React with this starter 由 facebook 创建,我是测试方面的新手。 现在我有一个关于图像的组件,它有
我是一名优秀的程序员,十分优秀!