.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
相关产品推荐
相关产品推荐

