3

We have an MVC.NET Core Web API app which uses an action filter to validate the controller's methods' arguments.

For validation we use FluentValidation framework. In the action filter, we find the IValidator<TModel> where TModel is the argument of the controller action, eg:

public async Task<IActionResult> Post([FromBody] TModel model)
{
}

In the filter's OnActionExecuting(ActionExecutingContext context) we find the proper validator (IValidator<TModel>), validate the arguments (context.ActionArguments) and if validation fails, we short-circuit by assigning the validation result into the context.Result - which means the execution never reaches the controller.

Basic principle is similar to hooking up FluentValidation into the MVC's ModelState validation pipeline but we need some extra things so we're doing it manually.

We would like to unit test both the controller and the validator. The problem is with unit testing the controller. In the test setup we instantiate the controller and call one of its methods. Now in production environment, the arguments will always get validated and actually make it to the controller method only if the arguments are valid. But when unit testing the controller, we can easily pass invalid arguments and get unexpected behaviour.

In principal, is there a way around this? Or do I actually need to make sure that in the test method I pass valid arguments to the controller?

EDIT:

We are also planning on integration testing (most likely using .NET Core's TestServer) to make sure the pipeline is working. In this post, I would like to discuss only the issue around invalid arguments passed from unit test methods to the controller.

1
  • Attributes, when testing controllers, are framework run time concerns when used in relation to what the attribute is decorating. That means in order to be able to test the controller with the attribute you would have to do an integration test with the necessary framework dependencies configured for the test. Commented Apr 20, 2018 at 13:42

3 Answers 3

1

You need to write Integration tests in ASP.NET Core see link: https://learn.microsoft.com/en-us/aspnet/core/testing/integration-testing?view=aspnetcore-2.0

The main goal: you test the same web api but it hosts in your tests.

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

Comments

0

First unit-test the validator so you have a clear definition of which parameters are valid and which are not.

Then, as you suggest in your question, you can take only the valid inputs and focus on them for unit-testing the controller.

Finally, you can create some integration tests with both valid and invalid parameters.

Comments

0

I agree with Nkosi said in comments, as the required attribute is not used directly by the controller, but used by the framework modelbinder to validate(fluent validation is also based on that), so calling the controller method alone can't unit test the existence of this attribute. it has to be integrated tested with the framework. However the asp.net core integration testing framework is too heavy, it can test the whole flow, not just model binding. We need a model binding intrgration test framework, running it can assert the modelstate valid or not, not caring the actuall controller action result. Maybe we can write one ourselves.

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.