我的控制器操作返回一个自定义ActionResult
,它根据某些验证逻辑执行成功或失败结果。这发生在ExecuteResult
内。
我的问题是,如何查看结果?
到目前为止,这是测试:
[TestFixture]
public class FormActionResultTests
{
TestController controller;
[SetUp]
public void SetUp()
{
ObjectFactory.Initialize(cfg =>
{
cfg.For<IFormHandler<TestModel>>().Use<TestModelHandler>();
});
controller = new TestControllerBuilder().CreateController<TestController>();
}
[Test]
public void Valid_input_returns_success_result()
{
var result = controller.Test(new TestModel { IsValid = true, IsValid2 = true })
.AssertResultIs<FormActionResult<TestModel>>();
var context = controller.ControllerContext;
result.ExecuteResult(context);
// how to verify result?
}
}
public class TestController : Controller
{
public ActionResult Test(TestModel model) {
return new FormActionResult<TestModel>(model, this.Content("Success"), View(model));
}
}
public class TestModel {
public bool IsValid { get; set; }
public bool IsValid2 { get; set; }
}
public class TestModelHandler : IFormHandler<TestModel>
{
public void Handle(TestModel form, IValidationDictionary validationDictionary)
{
}
}
这最终对我有用(使用NSubstitute):
[Test]
public void Valid_input_returns_success_result()
{
var result = new FormActionResult<TestModel>(new TestModel { IsValid = true, IsValid2 = true },
new ContentResult { Content = "Success" }, new ContentResult { Content = "Failed" });
var sb = new StringBuilder();
var response = Substitute.For<HttpResponseBase>();
response.When(x => x.Write(Arg.Any<string>())).Do(ctx => sb.Append(ctx.Arg<string>()));
var httpContext = Substitute.For<HttpContextBase>();
httpContext.Response.Returns(response);
var controllerContext = new ControllerContext(httpContext, new RouteData(), new TestController());
result.ExecuteResult(controllerContext);
sb.ToString().ShouldEqual("Success");
}
答案 0 :(得分:1)
应该测试控制器在它们的情况下它们返回正确的ActionResult,并且ActionResultTest的Action或失败应该由ActionResultTest测试,它与控制器无关。单元测试意味着单个单元测试 - 但您在同一测试中测试控制器和ActionResult,这是不正确的。要测试ActionResult,首先想象一下ActionResult所做的一切,就是将结果写入HttpResponse。让我们重写您的代码,使用Moq为StringWriter
提供ControllerContext.HttpContext.HttpResponse.Output
[Test]
public void Valid_input_returns_success_result()
{
var result = controller.Test(new TestModel { IsValid = true, IsValid2 = true })
.AssertResultIs<FormActionResult<TestModel>>();
var context = controller.ControllerContext;
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
StringWriter actionResultOutput = new StringWriter();
mockHttpContext.Setup(x => x.Response.Output).Returns(actionResultOutput);
context.HttpContext = mockHttpContext.Object;
result.ExecuteResult(context);
// how to verify result? Examine actionResultOutput
}
剩下的就是检查actionResultOutput。例如,如果您的操作结果设计为在验证正常时返回字符串“Success”,并在验证失败时返回“Error”,请将这些字符串与actionResultOutput.ToString()
进行比较。如果您的结果视图生成的html更复杂,您可以使用HtmlAgilityPack更深入地检查输出
答案 1 :(得分:-1)
您应该编写一个关于Test-action的简单单元测试,并在返回的操作结果上断言。您不应该依赖于测试中的MVC框架。只需创建一个新的TestController实例并调用Test方法。