无法使用Moq模拟ASP.NET Web API中的Configuration.Formatters
模拟ASP.NET Web API的Configuration.Formatters.JsonFormatter进行单元测试
我来帮你搞定这个单元测试里模拟JsonFormatter的问题!你的Register方法依赖Controller的Configuration.Formatters.JsonFormatter来构建ObjectContent,用Moq可以轻松实现这个模拟,下面是具体的步骤和代码示例:
方法1:使用实际的JsonMediaTypeFormatter(简单场景)
如果你的方法只是用JsonFormatter来序列化内容,不需要验证它的调用行为,直接用真实的JsonFormatter实例就足够了,步骤如下:
- 先模拟
HttpConfiguration对象,然后给它的Formatters.JsonFormatter属性返回一个实际的JsonMediaTypeFormatter - 将模拟好的Configuration赋值给你的ApiController实例
// 1. 创建模拟的HttpConfiguration var mockConfig = new Mock<HttpConfiguration>(); // 2. 实例化真实的JsonMediaTypeFormatter(可按需配置序列化规则) var jsonFormatter = new JsonMediaTypeFormatter { SerializerSettings = new JsonSerializerSettings { // 比如设置忽略循环引用、格式化输出等 ReferenceLoopHandling = ReferenceLoopHandling.Ignore, Formatting = Formatting.Indented } }; // 3. 配置Mock,让它返回我们创建的JsonFormatter mockConfig.Setup(config => config.Formatters.JsonFormatter).Returns(jsonFormatter); // 4. 把Mock的Configuration赋值给你的Controller var testController = new YourApiController(); testController.Configuration = mockConfig.Object;
方法2:完全模拟JsonMediaTypeFormatter(需验证行为时)
如果需要验证JsonFormatter的某个方法或属性是否被调用,就可以用Moq来模拟它:
// 1. 模拟JsonMediaTypeFormatter var mockJsonFormatter = new Mock<JsonMediaTypeFormatter>(); // 2. 配置需要模拟的属性或方法,比如SerializerSettings mockJsonFormatter.Setup(f => f.SerializerSettings) .Returns(new JsonSerializerSettings { /* 自定义序列化设置 */ }); // 3. 模拟HttpConfiguration并关联JsonFormatter var mockConfig = new Mock<HttpConfiguration>(); mockConfig.Setup(config => config.Formatters.JsonFormatter).Returns(mockJsonFormatter.Object); // 4. 赋值给Controller var testController = new YourApiController(); testController.Configuration = mockConfig.Object;
测试Register方法的完整示例
完成模拟后,就可以正常测试你的Register方法了:
// 准备测试数据 var testModel = new YourRegistrationModel(); // 你的业务Model实例 var testErrors = new List<string> { "用户名已存在", "密码长度至少为6位" }; // 调用被测方法 var response = testController.Register(testModel); // 断言结果 Assert.AreEqual(HttpStatusCode.BadRequest, response.StatusCode); // 验证Content的类型和内容是否符合预期 var objectContent = response.Content as ObjectContent<List<string>>; Assert.IsNotNull(objectContent); Assert.AreEqual(testErrors, objectContent.Value);
小提示
- 大部分场景下,用真实的JsonMediaTypeFormatter就足够了,模拟它更多是为了验证调用行为,或者在特殊序列化场景下自定义规则
- 务必确保Controller实例的Configuration属性被正确赋值,否则会触发空引用异常
内容的提问来源于stack exchange,提问作者Wai Yan Hein
相关产品推荐
相关产品推荐

