如何在单元测试中创建json post到MVC控制器
本文关键字:post MVC 控制器 json 创建 单元测试 | 更新日期: 2023-09-27 18:12:08
有一个方法的控制器,它期望一个json post,如…
public class MyController : Controller
{
[HttpPost]
public ActionResult PostAction()
{
string json = new StreamReader(Request.InputStream).ReadToEnd();
//do something with json
}
}
你如何设置一个单元测试发送post数据到控制器,当你试图测试它?
要传递数据,您可以使用模拟的http上下文设置控制器上下文,并传递请求体的假流。
使用moq来接收请求。
[TestClass]
public class MyControllerTests {
[TestMethod]
public void PostAction_Should_Receive_Json_Data() {
//Arrange
//create a fake stream of data to represent request body
var json = "{ '"Key'": '"Value'"}";
var bytes = System.Text.Encoding.UTF8.GetBytes(json.ToCharArray());
var stream = new MemoryStream(bytes);
//create a fake http context to represent the request
var mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Setup(m => m.Request.InputStream).Returns(stream);
var sut = new MyController();
//Set the controller context to simulate what the framework populates during a request
sut.ControllerContext = new ControllerContext {
Controller = sut,
HttpContext = mockHttpContext.Object
};
//Act
var result = sut.PostAction() as ViewResult;
//Assert
Assert.AreEqual(json, result.Model);
}
public class MyController : Controller {
[HttpPost]
public ActionResult PostAction() {
string json = new StreamReader(Request.InputStream).ReadToEnd();
//do something with json
//returning json as model just to prove it received the data
return View((object)json);
}
}
}
有了这些,现在有一些建议。
不要重新发明轮子。
MVC框架已经提供了解释发送给控制器动作的数据的功能(横切关注点)。这样你就不用担心要给模型补水了。框架将为您完成这些工作。它将使你的控制器动作更干净,更容易管理和维护。
如果可能的话,你应该考虑发送强类型的数据给你的操作。
public class MyController : Controller {
[HttpPost]
public ActionResult PostAction(MyModel model) {
//do something with model
}
}
框架基本上会通过使用ModelBinder进行所谓的参数绑定来完成您在操作中手动执行的操作。它将对请求体进行反序列化,并在匹配的情况下将传入数据的属性绑定到动作参数。
它也允许更容易的单元测试你的控制器
[TestClass]
public class MyControllerTests {
[TestMethod]
public void PostAction_Should_Receive_Json_Data() {
//Arrange
var model = new MyModel {
Key = "Value"
};
var sut = new MyController();
//Act
var result = sut.PostAction(model);
//Assert
//...assertions here.
}
}
您对HttpGet
和HttpPost
的控制器操作执行单元测试的方式相同。
[Test]
public void Test_MyController_PostAction()
{
var controller = new MyController();
ActionResult result = controller.PostAction();
// Assert here
}
假设你的动作需要一个模型参数。
[Test]
public void Test_MyController_PostAction()
{
var controller = new MyController();
ActionResult result = controller.PostAction(new SomeModel()); // Just pass as parameter
// Assert here
}