为什么自动固定装置不能创建这个类?



摘要

我在使用AutoFixture时遇到了一些奇怪的行为,这些行为似乎与类继承递归集合有关。我需要做些什么来允许AutoFixture创建这些类吗?我缺少的AutoFixture有什么限制吗?

详细信息

给定类别如下

public class SpecificNodeA : BaseNode
{
public SpecificNodeA(IEnumerable<BaseNode> childNodes) : base(childNodes)
{
}
}
public abstract class BaseNode
{
public List<BaseNode> ChildNodes { get; }
protected BaseNode(IEnumerable<BaseNode> childNodes)
{
ChildNodes = childNodes?.ToList();
}
}
public class SpecificNodeB : BaseNode
{
public SpecificNodeB(IEnumerable<BaseNode> childNodes) : base(childNodes)
{
}
}

以及的测试类别

[TestClass]
public class UnitTest1
{
[TestMethod]
public void CanGetSpecificNodeA()
{
var fixture = GetFixture();
var node = fixture.Create<SpecificNodeA>();
}
[TestMethod]
public void CanGetSpecificNodeB()
{
var fixture = GetFixture();
var node = fixture.Create<SpecificNodeB>();
}
private Fixture GetFixture()
{
var fixture = new Fixture();
fixture.Customizations.Add(
new TypeRelay(
typeof(BaseNode),
typeof(SpecificNodeA)));
fixture.Behaviors.OfType<ThrowingRecursionBehavior>().ToList()
.ForEach(b => fixture.Behaviors.Remove(b));
fixture.Behaviors.Add(new OmitOnRecursionBehavior());
return fixture;
}
}

我在尝试创建SpecificNodeB的实例时收到以下错误

Test method AutoFixtureTest.UnitTest1.CanGetSpecificNodeB threw exception: 
AutoFixture.ObjectCreationExceptionWithPath: AutoFixture was unable to create an instance from AutoFixtureTest.SpecificNodeA, most likely because it has no public constructor, is an abstract or non-public type.
Request path:
AutoFixtureTest.SpecificNodeB
System.Collections.Generic.IEnumerable`1[AutoFixtureTest.BaseNode] childNodes
System.Collections.Generic.IEnumerable`1[AutoFixtureTest.BaseNode]
AutoFixtureTest.BaseNode
AutoFixtureTest.SpecificNodeA

如果我将类更改为没有集合(如下所示(,它们可以正常工作

public class SpecificNodeA : BaseNode
{
public SpecificNodeA(int nodeId) : base(nodeId)
{
}
}
public abstract class BaseNode
{
public int NodeId { get; }
protected BaseNode(int nodeId)
{
NodeId = nodeId;
}
}
public class SpecificNodeB : BaseNode
{
public SpecificNodeB(int nodeId) : base(nodeId)
{
}
}

对我来说,AutoFixture不能创建这些类似乎很奇怪,因为它们相当简单,并且错误消息指示它是

无法从AutoFixtureTest创建实例。SpecificNodeA

没有意义,因为它在第一个单元测试中可以清楚地看到。

我需要做些什么来允许AutoFixture创建这些类吗?AutoFixture是否存在我遗漏或理解错误的某些限制或方面?

之所以会发生这种情况,是因为您添加的OmitOnRecursionBehavior在达到递归限制时将生成OmitSpecimen结果。这对属性很好,但对构造函数调用不起作用。

我认为解决问题最简单的方法是用NullRecursionBehavior替换OmitOnRecursionBehavior。

Omit和Null之间的区别在于,NullRecursionBehavior将不依赖于返回OmitSpecimen值,而只是在递归限制下返回Null值。当您有递归类型时,这通常正是您想要的。

最新更新