10

我正在为一些依赖于一些配置设置的帮助程序类编写一些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 文件?

4

2 回答 2

12

如果您的代码假定它们在 . app.config,那么 xUnit.net 支持通过提供一个将它们连接到那里(通常当测试在 DLL 文件中时,这意味着您 AssemblyName.dll.config在项目输出中获得一个文件,运行程序将其加载为设置(如果它在加载时存在)。

显然,首先使用 DI 原则来删除这些依赖项并没有什么坏处,但我想说,在你真正开始测试之前不要弄乱代码。

为了保持干燥,请将 app.config 放在中心位置并将其添加为链接(通过对话框中“打开”按钮上的箭头)。(是的,有很多不喜欢的地方——只有当你觉得它是最不邪恶的方法时才使用。)


需要注意的一件事是,除非您要求重新加载程序集,否则不会在 GUI 运行器中重新加载更改。

于 2012-05-25T22:32:33.500 回答
4

从更复杂的项目和团队工作的角度来看,我建议:

  1. xUnit 项目的单独 .config文件(它利用独立的配置和日志记录来运行测试)
  2. 单独为 xUnit 项目设置依赖注入.config 读取

我们的团队正在使用这种 xUnit init & dispose模式:

    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();
        }
    }
于 2020-02-27T00:47:37.680 回答