Answered Unit Test Filter Attribute?

beantownace

Active member
Joined
Feb 15, 2019
Messages
25
Programming Experience
5-10
Hello all,

I am struggling unit testing this particular method in a Utilities class I have. I am able to test the validate model for data annotations with ValidateModel works awesome. Any idea how can I test this method to get these lines covered thanks for any help:

[AttributeUsage(AttributeTargets.Method)]
public class SuppressModelStateInvalidFilterAttribute : Attribute, IActionModelConvention
{
private static readonly Type ModelStateInvalidFilterFactory = typeof(ModelStateInvalidFilter).Assembly.GetType("Microsoft.AspNetCore.Mvc.Infrastructure.ModelStateInvalidFilterFactory");

public void Apply(ActionModel action)
{
for (var i = 0; i < action.Filters.Count; i++)
{
if (action.Filters is ModelStateInvalidFilter || action.Filters.GetType() == ModelStateInvalidFilterFactory)
{
action.Filters.RemoveAt(i);
break;
}
}
}
}
 
You are punking us right?

In the arrange phase setup a ActionModel whose Filters property is of the class ModelStateInvalidFilter or ModelStateInvalidFilterFactory, as well as other object types that implement IList.

In the action phase, pass in that ActionModel.

In the assert phase, verify that the your class' RemoveAt() was called, or not called as appropriate.
 
Last edited:
For validating the model I am using this in the unit tests:


ValidationResult:
private IList<ValidationResult> ValidateModel(object model)

              {

                     var validationResults = new List<ValidationResult>();

                     var ctx = new ValidationContext(model, null, null);

                     Validator.TryValidateObject(model, ctx, validationResults, true);

                     return validationResults;

              }
 
Last edited:
Perhaps I'm not understanding something. You say that you want to do a unit test on an attribute class. So do a unit test on the attribute class. Currently with the code in post #4, you seem to be trying to do a full integration test.
 
Perhaps I'm not understanding something. You say that you want to do a unit test on an attribute class. So do a unit test on the attribute class. Currently with the code in post #4, you seem to be trying to do a full integration test.
.Net Core now has the ability to automatically handle model state 400 responses where in the past with MVC you had to handle it with ModelState.IsValid within your action results. So there are two options 1.) you apply the suppress model invalid at the startup file where that will auto validate and throw the bad request but it will never enter your action in the controller OR 2.) in my case I want to control in certain actions I want to actually get into the action for the controller because I want to log for example the request coming in that is where I tag a controller action with [SuppressModelStateInvalidFilter]. In my case then you need to create an extension for the filter attribute as I show in my original post.

In order to test the data annotations what I posted for ValidateModel handles unit testing the model. However I am trying to figure out how to test the extension filter as I can't find any examples to me its similar to how you would have to unit test the OnAuthorize attribute so that was why I posted.
 
Yes I understand that .NET Core has that support. But that still doesn't answer my question of why are you doing a full integration test instead of a unit test.

Let me put it this way. Let's say you've designed a new kind of propeller for an airplane. A unit test of the propeller would be to put that propeller an an axle and put that into a wind tunnel. An integration test is to put that propeller on an airplane and take the plane out for a flight.
 
Yes I understand that .NET Core has that support. But that still doesn't answer my question of why are you doing a full integration test instead of a unit test.

Let me put it this way. Let's say you've designed a new kind of propeller for an airplane. A unit test of the propeller would be to put that propeller an an axle and put that into a wind tunnel. An integration test is to put that propeller on an airplane and take the plane out for a flight.
I see what your saying so the validate model tests are really not unit tests testing each model property correct?

i.e I have a lot of tests like this maybe I should not have as part of the unit test. I added them simply because I was trying to test the bad request for each one that would return such as for example (inputParameters is my model with all the dataannotations its a transport object). In these cases when I am testing each model data annotation property that is when I am not crossing into integration tests.

Unit tes:
Assert.IsTrue(ValidateModel(inputParameters).Any(v => v.MemberNames.Contains("CustomerId")));
 
Last edited:
Back
Top Bottom