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

如何使用AutoFixture为被测类的只读属性指定自定义值?

用AutoFixture设置公共只读属性的方法

根据只读属性的实现方式,有几种不同的解决办法:

1. 只读属性通过构造函数初始化

如果你的类是通过构造函数参数来初始化只读属性的(这是最推荐的设计方式),AutoFixture可以直接通过With方法指定对应属性的值,它会自动匹配到构造函数参数:

// 被测类示例
public class SomeClass
{
    public int SomeReadonlyProperty { get; }
    public SomeClass(int someReadonlyProperty)
    {
        SomeReadonlyProperty = someReadonlyProperty;
    }
}

// 测试代码
var targetValue = 42;
var sut = _fixture.Build<SomeClass>()
    .With(m => m.SomeReadonlyProperty, targetValue)
    .Create();

也可以直接指定构造函数参数名来赋值:

var sut = _fixture.Build<SomeClass>()
    .With("someReadonlyProperty", targetValue)
    .Create();

2. 只读属性无对应构造函数参数(私有setter或内部初始化)

如果只读属性没有公开的构造函数参数可以利用,只能通过反射修改属性值。可以在Build链中用Do方法完成:

var targetValue = "自定义值";
var sut = _fixture.Build<SomeClass>()
    .Do(instance => 
    {
        var property = typeof(SomeClass).GetProperty(nameof(SomeClass.SomeReadonlyProperty));
        // 获取私有setter方法
        var setterMethod = property.GetSetMethod(true);
        setterMethod.Invoke(instance, new object[] { targetValue });
    })
    .Create();

如果需要重复使用这个逻辑,可以封装成自定义定制器:

public class SomeClassCustomization : ICustomization
{
    private readonly string _customValue;
    public SomeClassCustomization(string customValue) => _customValue = customValue;

    public void Customize(IFixture fixture)
    {
        fixture.Customize<SomeClass>(composer => composer
            .Do(instance => 
            {
                var prop = typeof(SomeClass).GetProperty(nameof(SomeClass.SomeReadonlyProperty));
                var setter = prop.GetSetMethod(true);
                setter.Invoke(instance, new object[] { _customValue });
            }));
    }
}

// 使用定制器
_fixture.Customize(new SomeClassCustomization("重复使用的自定义值"));
var sut = _fixture.Create<SomeClass>();

3. C# 9+的Init-Only属性

如果你的只读属性是用get; init;声明的(C# 9及以上版本),AutoFixture 4.15.0及以上版本支持直接用With方法设置,无需额外操作:

// 被测类示例
public class SomeClass
{
    public string SomeInitOnlyProperty { get; init; }
}

// 测试代码
var targetValue = "Init值";
var sut = _fixture.Build<SomeClass>()
    .With(m => m.SomeInitOnlyProperty, targetValue)
    .Create();

内容的提问来源于stack exchange,提问作者Anton

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 01:38:41