我正在为一些依赖于某些配置设置的辅助类编写一些xUnit测试,这些配置设置通常存储在正在执行的项目的App.config或Web.config中。
配置如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="FileNamePattern" value="\\d{8}_\\w{4:20}\.png"/>
<!-- and the likes -->
</appSettings>
</configuration>
我正在使用GUI运行程序(xunit.gui.clr4.exe)和xUnit控制台运行程序(在Jenkins CI服务器上)运行xUnit 1.9。目前,我可以通过手动设置xunit.gui.clr4.exe.config和xunit.console.exe.config文件,将这些配置值“注入”到测试环境中;然而,这很乏味且容易出错。
我还可以在灯具中模拟这些配置设置。但是在10个不同的文件中使用相同的夹具是相当重复的。
是否有更好的方法可以使用xUnit模拟这些配置设置,例如为测试项目提供App.config文件?
答案 0 :(得分:10)
如果你的代码假定它们在app.config
中,那么xUnit.net支持通过提供它们来连接它们(通常当测试在DLL文件中时,这意味着你得到{{1}如果在加载时存在,则运行器加载的项目输出中的文件作为设置。
显然,首先使用DI原则去除这些依赖关系并没有什么坏处,但是我会说在你真正首先测试它之前不要搞乱代码。
要保持DRY,请将app.config放在中央位置并将其添加为链接(通过对话框中“打开”按钮上的箭头)。 (是的,有很多不喜欢的东西 - 只有当你觉得它是最邪恶的方法时才使用。)
需要注意的一点是,除非您要求重新加载程序集,否则不会在GUI运行程序中重新加载更改。
答案 1 :(得分:1)
从更复杂的项目和团队合作的角度来看,我建议:
我们的团队正在使用这种xUnit模式初始化并处理:
public class MyTest : IDisposable
{
public IServiceProvider Services { get; private set; }
public MyProjectOptions Options { get; private set; }
public Logger Logger { get; private set; }
private void Configure()
{
// appsettings.workspace.json for custom developer configuration
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.AddJsonFile("appsettings.workspace.json", optional: true)
.Build();
Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.LiterateConsole()
.WriteTo.RollingFile("logs/{Date}-log.txt")
.CreateLogger();
Options = configuration.GetSection("MyProject").Get<MyProjectOptions>();
var services = new ServiceCollection();
services.AddSingleton<ILogger>(s => Logger);
// other DI logic and initializations ...
//services.AddTransient(x => ...);
Services = services.BuildServiceProvider();
}
public MyTest()
{
Configure();
// ... initialize data in the test database ...
var data = Services.GetService<TestDataService>();
data.Clean();
data.SeedData();
}
public void Dispose()
{
// ... clean-up data in the test database ...
var data = Services.GetService<TestDataService>();
data.Clean();
}
}