如何使用AutoFixture生成指定属性固定值的实例?
解决AutoFixture生成固定State的Order实例问题
核心问题解析
你遇到的问题有两个关键点:
Order是C# record类型,其属性为init-only只读属性,原测试代码中fixture.Build(o => o.State, OrderState.Initial)的API用法错误,无法修改只读属性。Filter是静态类,不能通过new Filter()调用静态方法,这是测试失败的隐性原因。
正确实现方式
方式一:使用Build<T>().With()指定固定属性
通过AutoFixture的Build<T>结合With方法,可以固定指定属性的值,其余属性由AutoFixture自动生成随机值:
[Fact] public void Returns_only_orders_with_initial_state() { // Arrange var fixture = new Fixture(); var order1 = fixture.Build<Order>() .With(order => order.State, OrderState.Initial) .Create(); var allOrders = new[] { fixture.Build<Order>().With(o => o.State, OrderState.State1).Create(), fixture.Build<Order>().With(o => o.State, OrderState.State2).Create(), fixture.Build<Order>().With(o => o.State, OrderState.State3).Create(), order1 }; // Act var actual = Filter.ByState(allOrders, OrderState.Initial); // 直接调用静态方法,无需实例化 // Assert actual.Should().BeEquivalentTo(new[] { order1 }); }
方式二:利用record的with表达式(AutoFixture 4.17+)
如果使用AutoFixture 4.17及以上版本,可以直接结合record的with语法,写法更简洁:
// 生成固定State的Order实例 var order1 = fixture.Create<Order>(o => o with { State = OrderState.Initial });
简化重复代码
如果需要多次生成指定State的Order,可以封装一个扩展方法减少重复代码:
public static class FixtureExtensions { public static Order CreateOrderWithState(this IFixture fixture, OrderState state) { return fixture.Build<Order>().With(o => o.State, state).Create(); } }
调用时只需:
var order1 = fixture.CreateOrderWithState(OrderState.Initial); var allOrders = new[] { fixture.CreateOrderWithState(OrderState.State1), fixture.CreateOrderWithState(OrderState.State2), fixture.CreateOrderWithState(OrderState.State3), order1 };
内容的提问来源于stack exchange,提问作者Basin
相关产品推荐
相关产品推荐

