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

如何在NUnit中使用Moq模拟IStreamReader,解决单元测试运行报错问题

错误原因
  • IFormFile的OpenReadStream方法未配置Mock返回,默认返回null。同时你在设置IStreamReader.GetReader的Mock规则时,当场调用mockFormFile.Object.OpenReadStream()得到的流实例,和业务代码实际执行时调用file.OpenReadStream()生成的实例不是同一个对象,导致Mock规则匹配失败,GetReader不会返回预期值。
  • IStreamReader.GetReader仅设置了调用匹配规则,未配置返回值,即使匹配到调用也会返回null,后续业务代码调用streamReader.ReadToEnd()时会触发空引用异常。
解决方案

修改测试代码,补全所有依赖的Mock规则即可,修改后的代码如下:

[Test]
public async Task CalculateSentimentFromTextFileEquality()
{
    // 构造测试用的文件流,写入测试文本
    var testContent = "测试文本内容";
    using var testStream = new MemoryStream();
    using var writer = new StreamWriter(testStream);
    writer.Write(testContent);
    writer.Flush();
    testStream.Position = 0;

    // Mock IFormFile,设置OpenReadStream返回我们构造的测试流
    var mockFormFile = new Mock<IFormFile>();
    mockFormFile.Setup(f => f.OpenReadStream()).Returns(testStream);

    var mockStreamReader = new Mock<IStreamReader>();
    // 设置GetReader匹配任意流,返回实际的StreamReader实例读取测试流内容
    mockStreamReader.Setup(o => o.GetReader(It.IsAny<Stream>()))
        .Returns(new StreamReader(testStream));

    var mockServerClient = new Mock<IServerClient>();
    var mockResult = new SentimentResult
    {
        label = "Positive"
    };
    mockServerClient.Setup(o => o.PostAsync<SentimentResult, string>(It.IsAny<string>(), It.IsAny<string>()))
        .ReturnsAsync(mockResult);

    var sut = new SentimentService(mockStreamReader.Object, mockServerClient.Object);
    var result = await sut.CalculateSentimentFromTextFile(mockFormFile.Object);

    Assert.That(result, Is.EqualTo("Positive"));
}

如果需要更严格的参数匹配,可以把It.IsAny<Stream>()替换为testStream,即可校验GetReader传入的流是否为IFormFile返回的测试流。

内容的提问来源于stack exchange,提问作者Setu Kumar Basak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 19:45:03