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

.NET5环境下如何用xUnit和Moq实现自定义InputFormatter的单元测试

自定义InputFormatter单元测试简便实现方案

不需要对InputFormatterContext的依赖做复杂Mock,借助ASP.NET Core官方提供的DefaultHttpContext即可快速构造测试上下文,实现成本极低。

前置依赖

确保测试项目配置了ASP.NET Core框架引用,在测试项目的.csproj文件中添加如下配置:

<ItemGroup>
  <FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>

单元测试实现代码

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using System.Text;
using Xunit;

public class RawJsonBodyInputFormatterTests
{
    private readonly RawJsonBodyInputFormatter _testFormatter = new RawJsonBodyInputFormatter();

    [Fact]
    public void CanReadType_StringType_ReturnsTrue()
    {
        var canRead = _testFormatter.CanReadType(typeof(string));
        Assert.True(canRead);
    }

    [Theory]
    [InlineData(typeof(int))]
    [InlineData(typeof(object))]
    [InlineData(typeof(Dictionary<string, object>))]
    public void CanReadType_NonStringType_ReturnsFalse(Type testType)
    {
        var canRead = _testFormatter.CanReadType(testType);
        Assert.False(canRead);
    }

    [Fact]
    public async Task ReadRequestBodyAsync_WithJsonContent_ReturnsRawStringCorrectly()
    {
        // 构造测试请求内容
        const string testJson = "{\"userId\":123,\"userName\":\"testUser\"}";
        var requestBodyStream = new MemoryStream(Encoding.UTF8.GetBytes(testJson));

        // 构造模拟HttpContext,无需Mock
        var mockHttpContext = new DefaultHttpContext();
        mockHttpContext.Request.Body = requestBodyStream;
        mockHttpContext.Request.ContentType = "application/json";

        // 直接构造InputFormatterContext
        var formatterContext = new InputFormatterContext(
            httpContext: mockHttpContext,
            modelName: string.Empty,
            modelState: new ModelStateDictionary(),
            metadata: new Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DefaultModelMetadata(
                ModelMetadataIdentity.ForType(typeof(string))),
            readerFactory: (stream, encoding) => new StreamReader(stream, encoding)
        );

        // 执行测试方法
        var result = await _testFormatter.ReadRequestBodyAsync(formatterContext);

        // 结果校验
        Assert.True(result.IsModelSet);
        Assert.Equal(testJson, result.Model as string);
    }
}

方案说明

  • DefaultHttpContext是ASP.NET Core官方提供的轻量模拟实现,专门用于单元测试场景,比自定义Mock的稳定性更高
  • 仅当需要模拟异常抛出、特殊属性返回等边缘场景时,才需要配合Moq使用,常规功能测试用上述方案即可覆盖
  • 测试代码没有复杂的Mock配置,维护成本极低

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 06:39:01