You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 04:12:09