14

A controller in my ASP.NET MVC application pre-populates form data displayed by my view according to a couple of fairly straight forward rules.

It seems like this would be a good thing to cover in my unit testing. But the only way I could see to verify the correct data is placed in the form, would be to extract the logic from the controller in what feels like an unnatural way.

Can someone suggest ways to approach this?

All the examples I've found of unit testing controllers seemed very trivial, such as verifying it returned the expected type of view. I'm not sure I even see the value in that.

2 Answers 2

21

You can test by casting the returned object to the appropriate class, instead of using their base class (which is returned by default)

For example, to test the default AccountController you'd so something like this:

var controller = new AccountController();
var result = controller.LogOn() as ViewResult;
var model = result.Model as LogOnModel;

Assert.IsTrue(model.RememberMe); // assuming you "pre-populated" enabled the checkbox

Checking if the returned object is filled with the right data does not seem "unnatural" to me, or did you meant it differently?

Sign up to request clarification or add additional context in comments.

1 Comment

Ah... result.Model looks helpful.
12

I would agree that testing the type of view returned would be somewhat pointless. However, testing that the expected "view" was returned along with its correct data would be a valid test case IMO.

For example here is a singular edit test case for an edit controller. Note, that this example is making use of Moq and Nunit but that aside it's fairly straight forward.

Note, that that ViewResult is cast to the expected view model and the assertions are then made against the expected contact.

Test:

[Test]
public void Edit_Get_Should_Lookup_Contact_From_Repository_And_Return_Edit_View()
{
    // arrange
    var _repository = new Mock<IContactRepository>();

    var expectedContact = new Contact
    {
        First = "first",
        Last = "last",
        Email = "[email protected]"
    };

    var mockContext = new Mock<ControllerContext>();
    _repository.Setup(x => x.GetById(It.IsAny<int>())).Returns(expectedContact);

    var controller = new ContactController(_repository.Object)
    {
        ControllerContext = mockContext.Object
    };

    // act
    var result = controller.Edit(1) as ViewResult;
    var resultData = (Contact)result.ViewData.Model;

    // assert
    Assert.AreEqual("Edit", result.ViewName);
    Assert.AreEqual(expectedContact.First, resultData.First);
    Assert.AreEqual(expectedContact.Last, resultData.Last);
    Assert.AreEqual(expectedContact.Email, resultData.Email);
}

Controller:

[HttpGet]
public ActionResult Edit(int id)
{
    var contact = _repository.GetById(id);

    return View("Edit", contact);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.