我非常欣赏AutoFixture的强大功能以及XUnit的理论。我最近采用了encapsulating customizations并通过属性将它们提供给我的测试。
在某些情况下,我需要一次性场景来运行我的测试。当我使用AutoDomainDataAttribute时,如上所述,我可以要求IFixture并期望得到属性创建的相同实例吗?
在我的场景中,我默认使用MultipleCustomization进行集合等。但是,在这种情况下,我只想将一个项目发送到我的SUT的构造函数。所以,我已经定义了我的测试方法:
[Theory, AutoDomainData]
public void SomeTest(IFixture fixture) {
fixture.RepeatCount = 1;
var sut = fixture.CreateAnonymous<Product>();
...
}
不幸的是,我在创建匿名产品时遇到异常。如果我要求Product作为具有这些属性的方法参数,其他测试工作正常。在这种特殊情况下,这只是一个问题,我希望fixture参数与我的AutoDomainDataAttribute创建的相同。
产品的构造函数需要一个IEnumerable通常会填充3个项目,因为我通过AutoDomainData进行了自定义。目前,我的DomainCustomization是一个由MultipleCustomization和AutMoqCustomization组成的CompositeCustomization,按顺序排列。
例外是:“InvalidCastException:无法将'Castle.Proxies.ObjectProxy'类型的对象强制转换为'Product'。”
答案 0 :(得分:7)
如果您需要与属性中活动的实例相同的Fixture实例,您可以在自定义中将Fixture注入其自身,如下所示:
public class InjectFixtureIntoItself : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Inject(fixture);
}
}
请记住在 AutoMoqCustomization之前将它添加到您的CompositeCustomization ,因为IFixture是一个接口,如果首先是AutoMoqCustomization,那么您将获得一个Mock实例--AFAICT,&#39;当前动态城堡代理正在发生什么。
但是,如果你真的需要一个Fixture实例,为什么不写一个常规的,命令式的测试方法:
[Fact]
public void SomeTest()
{
var fixture = new Fixture().Customize(new DomainCustomization());
fixture.RepeatCount = 1;
var sut = fixture.CreateAnonymous<Product>();
// ...
}
在我看来要容易得多......我偶尔也会这样做......
不过,我想知道你是否不能以不同的方式表达你的API或测试用例,以使整个问题消失。我非常很少发现我现在必须操纵RepeatCount
属性,所以我想知道你为什么要这样做?
这可能是单独的Stack Overflow问题的主题,但是......