c# - 使用动态参数对 post 方法进行单元测试
问题描述
我的 web api 控制器中有一个带有动态参数的 post 方法
public IEnumerable<Product> Post([FromBody]dynamic value)
{
int productId;
try
{
productId = Convert.ToInt32(value.productId.Value);
}
catch
{
return null;
}
return _data.Products.Where(y => y.Id == productId).ToList();
}
我正在尝试使用 Moq 框架工作对此进行单元测试,这就是我所拥有的
public void PostRequestWithSingleProductTest()
{
var reqBody = new {productId = 1};
var reqObject = new Mock<HttpRequestMessage>();
reqObject.Setup(rq => rq.ToString()).Returns(JsonConvert.SerializeObject(reqBody));
var response = _productController.Post(reqObject.Object);
Assert.IsNotNull(response);
}
响应始终为空,当我调试测试时,我可以看到传递的值是 {{productId:1}} 但编译器由于某种原因无法读取它并且它正在抛出Microsoft.CSharp.Runtime .Binder 异常。
我已使用 assembly: InternalsVisibleTo()将测试程序集标记为朋友。
请分享你的想法。
谢谢。
解决方案
问题是被测方法假定productId
是可为空的,因此.Value
. 当测试通过实际整数而不是可空整数时发生异常。
public void PostRequestWithSingleProductTest() {
//Arrange
int? productId = 1;
var value = new { productId };
//assuming _productController already created and injected with dependency
//Act
var response = _productController.Post(value);
//Assert
Assert.IsNotNull(response);
}
理想情况下,您应该使用强类型模型
public class PostProductModel {
[Required]
public int productId { get; set; }
}
这将允许框架进行正确的模型绑定
public IHttpActionResult Post([FromBody]PostProductModel value) {
if(ModelState.IsValid) {
var result = _data.Products.Where(y => y.Id == value.productId).ToList();
return Ok(result);
}
return BadRequest(ModelState);
}
并大大简化了对目标方法进行单元测试的能力。
public void PostRequestWithSingleProductTest() {
//Arrange
var value = new PostProductModel { productId = 1 };
//assuming _productController already created and injected with dependency
//Act
var response = _productController.Post(value) as OkObjectResult;
//Assert
Assert.IsNotNull(response);
}
推荐阅读
- python - 将日志级别设置为处理程序在 python 中不起作用
- amazon-web-services - 无法在 AWS ubuntu 上安装任何东西
- python-3.x - 文本分类器训练数据未通过 spacy debug-data CLI 正确加载
- laravel - 如何使用 Laravel 模型保存和检索 base64 编码数据
- azure - 如何将部门添加到 Azure AD 令牌
- php - Symfony 3.4 为什么 Formtype 的 CollectionType 不发布值
- c - 当流不为 0 时 fgetc() 返回 EOF
- javascript - 在java脚本中循环有限的对象
- javascript - 需要为我的简单 ToDoList 添加一个 localStorage
- javascript - 在 Django 中搜索 javascript