geo*_*rtz 6 c# asp.net-mvc unit-testing
使用带有期望 json 帖子的方法的控制器,例如...
public class MyController : Controller
{
[HttpPost]
public ActionResult PostAction()
{
string json = new StreamReader(Request.InputStream).ReadToEnd();
//do something with json
}
}
Run Code Online (Sandbox Code Playgroud)
当您尝试测试时,如何设置单元测试以将发布数据发送到控制器?
要传递数据,您可以使用模拟的 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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
有了这个,现在给一些建议。
不要重新发明轮子。
MVC 框架已经提供了用于解释发送到控制器操作(Cross-cutting 关注点)的数据的功能。这样您就不必担心必须为要使用的模型补水。该框架将为您完成。它将使您的控制器操作更清晰,更易于管理和维护。
如果可能,您应该考虑将强类型数据发送到您的操作。
public class MyController : Controller {
[HttpPost]
public ActionResult PostAction(MyModel model) {
//do something with model
}
}
Run Code Online (Sandbox Code Playgroud)
该框架基本上将通过使用其 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.
}
}
Run Code Online (Sandbox Code Playgroud)