使用动态参数对 post 方法进行单元测试
Unit testing a post method with a dynamic argument
我的网络 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);
}
响应始终为 null,当我调试测试时,我可以看到传递的值是 {{productId:1}} 但编译器由于某种原因无法读取它,它抛出一个Microsoft.CSharp.Runtime.Binder异常.
我已将测试程序集标记为朋友使用程序集: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);
}
我的网络 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);
}
响应始终为 null,当我调试测试时,我可以看到传递的值是 {{productId:1}} 但编译器由于某种原因无法读取它,它抛出一个Microsoft.CSharp.Runtime.Binder异常.
我已将测试程序集标记为朋友使用程序集: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);
}