unit testing controller

2019-05-11 12:30发布

问题:

I have a very simple scenario:

[HttpGet]
public ActionResult CreateUser()
{
    return View();
}

[HttpGet]
public ActionResult Thanks()
{
    return View();
}

[HttpPost]
public ActionResult CreateUser(CreateUserViewModel CreateUserViewModel)
{
    if (ModelState.IsValid)
    {
    return View("Thanks");
    }

    return View(CreateUserViewModel);
}

My unit test uses the testhelper from mvc contrib:

[Test]
public void UserController_CannotCreateUserWithNoLastName()
{
    // arrange
    UsersController UsersController = new UsersController();
    CreateUserViewModel CreateUserViewModel = new CreateUserViewModel();
    CreateUserViewModel.LastName = "";

    // act
    ActionResult result = UsersController.CreateUser(CreateUserViewModel);

    // assert
    result.AssertViewRendered().ForView("CreateUser");
}

When I open the browser and try to submit an invalid user (no lastname) it redirects to the createuser form but the unit test fails (it says that it redirects to thanks). Why is this? Can anyone see anything wrong? Thanks!

回答1:

Inside your unit test you should simulate that your model has an error because it's what you want to test (the error path). In your test the model is valid that's why it redirects you to the "Thanks" view. To simulate the error you can do that in your unit test before "act" section :

UsersController.ModelState.AddModelError("username", "Bad username"); 

Take a look on that example : http://www.thepursuitofquality.com/post/53/how-to-test-modelstateisvalid-in-aspnet-mvc.html

More about AddModelError method here : http://msdn.microsoft.com/en-us/library/system.web.mvc.modelstatedictionary.addmodelerror.aspx



回答2:

I beleive you are using DataAnnotations for LastName empty so validation will be performed by the ModelBinder. Unit test will skip ModelBinder and validation.

See this SO question for more details - call UpdateModel on the Controller manually