Melissa Avery-Weir
Melissa Avery-Weir

Reputation: 1357

How do I test response data using nUnit?

Django has a very handy test client/dummy web browser that one can use in test cases to verify the correctness of HTTP responses (e.g., status codes, context/model data). It does not require you to have the web server running, as it deals directly with the framework to simulate the calls.

I'd really love an nUnit (or similar) equivalent that we can slip right into our test suites. We're working in MVC3 and 4, and want to check things like successful 301 redirects, that model validation is correct, and that ViewModel data is correct in the views.

What's the best solution for this?

Upvotes: 1

Views: 646

Answers (2)

Nick
Nick

Reputation: 6588

To explicitly test the [Required] etc attributes on your object you will have extract the built in .net validation into another class. Then use that class in your controllers to validate your objects, instead of the Model.IsValid property on your controller.

The model validator class:

public class ModelValidator : IModelValidator
{
    public bool IsValid(object entity)
    {
        return Validate(entity, new List<ValidationResult>());
    }

    public IEnumerable<ValidationResult> Validate(object entity)
    {
        var validationResults = new List<ValidationResult>();
        Validate(entity, validationResults);
        return validationResults;
    }

    private static bool Validate(object entity, ICollection<ValidationResult> validationResults)
    {
        if (entity != null)
        {
            var validationContext = new ValidationContext(entity, null, null);
            return Validator.TryValidateObject(entity, validationContext, validationResults);    
        }

        return false;
    }
}

This could be verifiable in unit tests with the following:

public class MySampleEntity
{
    [Required]
    public string X { get; set; }

    [Required]
    public int Y { get; set; }
}

[TestFixture]
public class ModelValidatorTests
{
    [Test]
    public void GivenThePropertiesArePopulatedTheModelIsValid()
    {
        // arrange
        var _validator = new ModelValidator();
        var _entity = new MySampleEntity { X = "ABC", Y = 50 };

        // act
        var _result = _validator.IsValid(_entity);

        // assert
        Assert.That(_result, Is.True);
    }
}

Upvotes: 0

Nick
Nick

Reputation: 6588

ViewModel Data should be easy to check with the following:

    public T GetViewModelFromResult<T>(ActionResult result) where T : class
    {
        Assert.IsInstanceOf<ViewResult>(result);
        var model = ((ViewResult)result).Model;
        Assert.IsInstanceOf<T>(model);
        return model as T;
    }

    [Test]
    public void TheModelHasTheOrder()
    {
        var controller = new MyController();
        var result = controller.MyActionMethod();
        var model = GetViewModelFromResult<MyModel>();

        Assert.That(model, Is.SameAs(???));
    }

As for the model validation, if you are using the out of the box .net property attributes like [Required] etc, you can be pretty sure they will work fine, and won't need testing.

Upvotes: 1

Related Questions