问题
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();
}
}
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 : The lazily-initialized type does not have a public, parameterless constructor.
Is there a way that I can avoid this error and inject lazy objects when using autofixture?
回答1:
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.
来源:https://stackoverflow.com/questions/18307975/autofixture-constructer-injection-lazy-loading