私はMVC、ユニットテスト、モック、TDDを初めて使用します。私は可能な限りベストプラクティスに従うようにしています。
コントローラの単体テストを作成しましたが、正しいビューが返されるかどうかのテストに問題があります。ViewResult.ViewNameを使用する場合、コントローラーでビュー名を指定しないと、テストは常に失敗します。コントローラでViewNameを指定すると、ビューが存在しない場合でも、テストは常に合格します。
Response.Statusコードのテストも試みましたが、これは常に200を返します(MVC3ユニットテストの応答コードに対するDarin Dimitrovの回答から取得したコード)。私が目指しているのは、新しいビューを作成するときの古典的な赤、緑のリファクタリングであり、ライブに移行するときの404およびSystem.InvalidOperationExceptionエラーを回避することです。これは可能ですか?
以下のコード。
public class BugStatusController : Controller
{
public ActionResult Index(){
return View(); // Test always fails as view name isn’t specified even if the correct view is returned.
}
public ActionResult Create(){
return View("Create"); // Test always passes as view name is specified even if the view doesn’t exist.
}
}
[TestFixture]
public class BugStatusTests
{
private ViewResult GetViewResult(Controller controller, string controllerMethodName){
Type type = controller.GetType();
ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes);
object instance = constructor.Invoke(new object[] {});
MethodInfo[] methods = type.GetMethods();
MethodInfo methodInfo = (from method in methods
where method.Name == controllerMethodName
&& method.GetParameters().Count() == 0
select method).FirstOrDefault();
Assert.IsNotNull(methodInfo, "The controller {0} has no method called {1}", type.Name, controllerMethodName);
ViewResult result = methodInfo.Invoke(instance, new object[] {}) as ViewResult;
Assert.IsNotNull(result, "The ViewResult is null, controller: {0}, view: {1}", type.Name, controllerMethodName);
return result;
}
[Test]
[TestCase("Index", "Index")]
[TestCase("Create", "Create")]
public void TestExpectedViewIsReturned(string expectedViewName, string controllerMethodName){
ViewResult result = GetViewResult(new BugStatusController(), controllerMethodName);
Assert.AreEqual(expectedViewName, result.ViewName, "Unexpected view returned, controller: {0}, view: {1}", CONTROLLER_NAME, expectedViewName);
}
[Test]
[TestCase("Index", "Index")]
[TestCase("Create", "Create")]
public void TestExpectedStatusCodeIsReturned(string expectedViewName, string controllerMethodName)
{
var controller = new BugStatusController();
var request = new HttpRequest("", "http://localhost:58687/", "");
var response = new HttpResponse(TextWriter.Null);
var httpContext = new HttpContextWrapper(new HttpContext(request, response));
controller.ControllerContext = new ControllerContext(httpContext, new RouteData(), controller);
ActionResult result = GetViewResult(controller, controllerMethodName);
Assert.AreEqual(200, response.StatusCode, "Failed to load " + expectedViewName + " Error: " + response.StatusDescription);
}
}