我真的很欣赏 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 创建的参数相同。
由于我通过 AutoDomainData 进行了就地自定义,产品的构造函数需要一个 IEnumerable,该 IEnumerable 通常会填充 3 个项目。目前,我的 DomainCustomization 是由 MultipleCustomization 和 AutMoqCustomization 按顺序组成的 CompositeCustomization。
异常(exception)是:“InvalidCastException:无法将 'CaSTLe.Proxies.ObjectProxy' 类型的对象转换为 'Product' 类型。”
最佳答案
如果您需要与属性中的事件实例相同的 Fixture 实例,则可以在自定义中将 Fixture 注入(inject)自身,如下所示:
public class InjectFixtureIntoItself : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Inject(fixture);
}
}
请记住在 AutoMoqCustomization 之前将其添加到您的 CompositeCustomization 中,因为 IFixture 是一个接口(interface),如果 AutoMoqCustomization 先出现,您将获得一个 Mock 实例 - AFAICT,这就是动态 CaSTLe 代理目前正在发生的事情。
然而,如果你真的需要一个 Fixture 实例,为什么不写一个常规的、命令式的测试方法:
[Fact]
public void SomeTest()
{
var fixture = new Fixture().Customize(new DomainCustomization());
fixture.RepeatCount = 1;
var sut = fixture.CreateAnonymous<Product>();
// ...
}
在我看来这要容易得多......我自己也偶尔这样做......
不过,我想知道您是否不能以不同的方式来表达您的 API 或测试用例以使整个问题消失。我很少发现我必须操纵
RepeatCount
这些天来属性(property),所以我想知道您为什么要这样做?不过,这可能是另一个 Stack Overflow 问题的主题......
关于xunit - 如何修改我的自定义理论数据属性为 AutoFixture 创建的夹具?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13128446/