c# - 如何在 Autofac 的集成测试中注册 IOptions?

标签 c# .net asp.net-core integration-testing autofac

我正在使用我在实际应用程序中使用的相同 Autofac 模块注册编写集成测试。我使用这样的基类将其连接起来:

public abstract class ContainerFixture<TModule, TSubject> where TModule : Module, new() where TSubject : class
{
    protected IContainer Container { get; private set; } = null!;
    protected TSubject Subject { get; private set; } = null!;

    [SetUp]
    public void BaseSetUp()
    {
        var builder = new ContainerBuilder();
        builder.RegisterModule<TModule>();

        Container = builder.Build();
        Subject = Container.Resolve<TSubject>(); <- This is where it fails to resolve MyClass.
    }
}

这是我正在使用的模块:

public sealed class MyModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType<MyClass>().AsImplementedInterfaces().SingleInstance();
    }
}

这是我正在测试的类:

public sealed class MyClass
{
    private readonly MyClassOptions _options;

    public MyClass(IOptions<MyClassOptions> options)
    {
        _options = options.Value;
    }

    ...methods go here
}

将它作为一个合适的应用程序运行是可行的,因为在我的 Program.cs 文件中,我像这样绑定(bind)了我的选项类:

builder.Services
    .AddOptions<MyClassOptions>()
    .Bind(builder.Configuration.GetSection(MyClassOptions.Name));

然而,在运行我的实际测试时,那段代码显然从未运行过,因此无法解析 IOptions<MyClassOptions>MyClass 内和测试错误。

为了完整起见,我的测试看起来像这样:

public sealed class MyClassIntegrationTests : ContainerFixture<MyModule, MyClass>
{
    [Test]
    public void Test()
    {
        // Test goes here
    }
}

如何注册 IOptions<MyClassOptions在 Autofac 中使得 MyClass为我的测试正确解析?

最佳答案

那么,您需要为配置提供模拟。 如果您对实际的配置过程不感兴趣,我能想到的最简单的方法是使用简单的实例包装器:

public class OptionWrapper<T> : IOptions<T> where T : class
{
  public OptionWrapper(T value)
  {
    Value = value;
  }

  /// <summary>The default configured TOptions instance</summary>
  public T Value { get; }
}

然后您将在设置容器注册实例时使用它:

[SetUp]
public void BaseSetUp()
{
  var builder = new ContainerBuilder();
  builder.RegisterModule<TModule>();
  var options = new MyClassOptions()
  {
    // ...
  };
  builder.RegisterInstance(new OptionWrapper<MyClassOptions>(options))
       .As<IOptions<MyClassOptions>>();

  Container = builder.Build();
  Subject = Container.Resolve<TSubject>();
}

当容器解析时,您的配置实例被包装并返回给您的组件。

请注意以上代码未经测试,但它应该可以正常工作。

关于c# - 如何在 Autofac 的集成测试中注册 IOptions?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74658410/

相关文章:

c# - ServiceStack请求参数还是 session 变量?

c# - 更新 Entity Framework 中的实体

c# - EWS foreach 所有未读邮件不起作用

c# - index.html 未显示为默认页面

asp.net-core - 为什么在我的项目中 wwwroot 中不存在 bin 文件夹?

c# - 通过 POST、PUT 方法返回 400 Bad Request,但 GET 工作正常

c# - 常量与只读

c# - 使用字符串中的公钥验证 JWT

.net - 显示只有 "Close"或 "Cancel"按钮的错误对话框 (MessageBox)?

c# - 如何将查询字符串添加到 httpwebrequest