AutoFixture自定义布尔值时出现不符合预期的行为
问题原因与解决方案
为什么全局自定义被忽略?
AutoFixture的Build<T>()方法会创建一个独立的构建器实例,它不会继承或应用你在Fixture对象上通过Customize<T>()设置的全局自定义规则。这是设计上的明确区分:
fixture.Customize<T>()是全局级别的配置,仅作用于fixture.Create<T>()调用。Build<T>()是临时的、按需定制的构建链,所有配置都必须在这个链内明确声明。
解决方法
方法1:全局自定义 + Create<T>()
如果你的自定义需要全局生效,直接调用fixture.Create<Foo>()即可,全局配置会被正常应用:
[Fact] public void Autofixture_Global_Customization_Works() { var fixture = new Fixture(); fixture.Customize<Foo>( composer => composer.With(x => x.SomeBoolean, false) ); var model = fixture.Create<Foo>(); Assert.False(model.SomeBoolean); // 符合预期 }
方法2:在Build<T>()链内直接配置
如果必须使用Build<T>()(比如需要临时调整其他属性),直接在构建链中添加With配置即可。这种方式可以精准固定指定布尔值,其他布尔值会保持随机生成,完全适配多布尔值的复杂模型需求:
public class ComplexFoo { public bool FixedBoolean { get; set; } public bool RandomBoolean1 { get; set; } public bool RandomBoolean2 { get; set; } } [Fact] public void Autofixture_Build_Controls_Specific_Boolean() { var fixture = new Fixture(); var model = fixture.Build<ComplexFoo>() .With(x => x.FixedBoolean, false) // 固定目标属性 // 其他布尔值会自动按默认策略随机生成 .Create(); Assert.False(model.FixedBoolean); // RandomBoolean1、RandomBoolean2的值为随机,符合需求 }
补充说明
冻结布尔值确实不适用于多布尔值的复杂模型,因为冻结会影响所有该类型的实例生成。而上面的两种方法,尤其是Build<T>()的链式配置,既能精准固定指定布尔属性,又能保证其他属性(包括其他布尔值)按照AutoFixture的默认策略随机生成,完全匹配你的需求。
内容的提问来源于stack exchange,提问作者shaft
相关产品推荐
相关产品推荐

