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

C# xUnit单元测试构造函数中Moq配置值为空问题解决

问题原因

测试失败是3处Moq配置和代码写法错误导致的:

  1. IOptions<CallOptions>的Mock配置完全无效:options.SetReturnsDefault("test") 是给Mock对象自身的方法返回设置默认值,根本没有配置IOptions.Value属性返回合法的CallOptions实例,构造函数读取_options.Name时拿到的是空值,自然触发非空校验抛异常。
  2. CreateSut方法存在两处笔误:一是构造函数传参顺序颠倒,Country构造函数第一个参数是IOptions实例、第二个是Irepo实例,你写反了传入顺序;二是引用的Mock变量名不匹配,定义的变量名是options,调用时写的是_options,会直接触发编译错误。
  3. Irepo的Mock参数匹配类型错误:你Setup和Verify时用It.IsAny<List<string>>()匹配参数,但测试调用时传入的是string[]数组,二者类型不匹配,后续即使构造成功也会导致Verify失败。

*额外注意:你贴的业务类构造函数泛型参数有误,_options是CallOptions类型,构造函数参数应该写为IOptions<CallOptions> options,否则会出现泛型不匹配的编译错误。

修复方案

按以下步骤调整测试代码即可:

  • 正确配置IOptions Mock的Value属性,返回Name非空的CallOptions实例
  • 修正CreateSut中构造函数的传参顺序,统一Mock变量命名
  • 将Irepo相关Setup、Verify的参数匹配泛型改为IList<string>,和方法签名保持一致,兼容传入的数组类型
修正后的完整测试代码
public class ProcessorTests 
{
    private readonly Mock<Irepo> _repositoryMock;
    private readonly Mock<IOptions<CallOptions>> _optionsMock;

    public ProcessorTests()
    {
        _repositoryMock = new Mock<Irepo>();
        _optionsMock = new Mock<IOptions<CallOptions>>();
        // 正确配置IOptions的Value属性,返回Name非空的合法配置
        _optionsMock.Setup(o => o.Value).Returns(new CallOptions { Name = "test" });
    }

    private Country<CountryModel> CreateSut()
    {
        // 修正传参顺序:第一个是IOptions实例,第二个是Irepo实例
        return new Country<CountryModel>(_optionsMock.Object, _repositoryMock.Object);
    }

    [Fact]
    public async Task ShouldCheck()
    {
        GetRepoMock();
        await CreateSut().ProcessCall(new string[] { "TEST" });
        // 参数匹配改为IList<string>,兼容数组传入
        _repositoryMock.Verify(x => x.set(It.IsAny<IList<string>>()), Times.Once);
    }

    private void GetRepoMock()
    {
        // 参数匹配改为IList<string>,和方法签名保持一致
        _repositoryMock
            .Setup(m => m.set(It.IsAny<IList<string>>()))
            .ReturnsAsync(new Response<Code>(false, null, Enumerable.Empty<Code>()));
    }
}

补充:如果要覆盖构造函数的非空校验逻辑,可以单独写测试用例,配置IOptions返回Name为空的CallOptions,断言构造时抛出预期的ArgumentException即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 16:18:25