本文介绍了Autofixture 构造函数注入延迟加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的单元测试中使用了 autofixture,它作为 automocker 的工作方式很棒.

I am using autofixture in my unit tests and it is great the way that it works as an automocker.

但是,我在将延迟加载的对象注入我的类时遇到了问题.例如:

However I have a problem when injecting a lazy loaded object into my class. For example:

public class MyClass : IMyClass
{
    private Lazy<IMyInjectedClass> _myInjectedClassLazy;
    private IMyInjectedClass _myInjectedClass {
        get { return _myInjectedClassLazy.Value; }
    }

    public MyClass(Lazy<IMyInjectedClass> injectedClass)
    {
        _myInjectedClassLazy = _myInjectedClass;
    }

    public void DoSomething()
    {
        _myInjectedClass.DoSomething();
    }
}

然后当我尝试运行一个测试时,我使用 autofixture 来生成类:

Then when I try to run a test where I use autofixture to generate the class as so:

public class MyTests
{
    [Test]
    public void ShouldDoSomething()
    {
        var fixture = new Fixture().Customize(new AutoMoqCustomization());
        fixture.Behaviors.Remove(new ThrowingRecursionBehavior());
        fixture.Behaviors.Add(new OmitOnRecursionBehavior());

        var mockMyClass = fixture.Freeze<Mock<IMyClass>>();

        var sut = fixture.Create<MyClass>();

        sut.DoSomething();
    }
}

但是这段代码抛出了以下错误:

But this code throws the following error:

System.MissingMemberException : 延迟初始化的类型没有公共的、无参数的构造函数.

在使用 autofixture 时,有没有办法避免这个错误并注入惰性对象?

Is there a way that I can avoid this error and inject lazy objects when using autofixture?

推荐答案

FWIW,虽然我不同意这样做的动机,但你可以告诉 AutoFixture 如何创建 Lazy 的实例:

FWIW, although I disagree with the motivation for doing this, you can tell AutoFixture how to create an instance of Lazy<IMyInjectedClass>:

var fixture = new Fixture().Customize(new AutoMoqCustomization());
fixture.Behaviors.Remove(new ThrowingRecursionBehavior());
fixture.Behaviors.Add(new OmitOnRecursionBehavior());
fixture.Register(                                                   // Add this
    (IMyInjectedClass x) => new Lazy<IMyInjectedClass>(() => x));   // to pass

var mockMyClass = fixture.Freeze<Mock<IMyClass>>();

var sut = fixture.Create<MyClass>();

sut.DoSomething();

如果您需要重复执行此操作,则应考虑将其打包为自定义设置.

If you need to do this repeatedly, you should consider packaging this in a Customization.

这篇关于Autofixture 构造函数注入延迟加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!