.net 如何在Autofac集成测试中注册IOptions?

hrirmatl  于 2022-12-05  发布在  .NET
关注(0)|答案(1)|浏览(222)

我正在编写一个集成测试,使用的是我在实际应用程序中使用的相同的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文件中,我绑定了选项类,如下所示:

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

然而,当运行我的实际测试时,这段代码显然永远不会运行,所以它无法在MyClass和测试错误中解析IOptions<MyClassOptions>
为了完整起见,我的测试如下所示:

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

如何在Autofac中注册IOptions<MyClassOptions,以便为我的测试正确解析MyClass

tcomlyy6

tcomlyy61#

您需要为配置提供一个模拟。我能想到的最简单的方法是使用一个简单的示例 Package 器,假设您对实际的配置过程不感兴趣:

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>();
}

当容器解析时,配置示例将被 Package 并返回到组件。
请注意,以上代码未经测试,但它应该可以正常工作。

相关问题