Answered Unit Test Filter Attribute?

beantownace

Member
Joined
Feb 15, 2019
Messages
8
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;
}
}
}
}
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
1,959
Location
Chesapeake, VA
Programming Experience
10+
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:

beantownace

Member
Joined
Feb 15, 2019
Messages
8
Programming Experience
5-10
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:

Sheepings

Senior Programmer
Staff member
Joined
Sep 5, 2018
Messages
1,679
Location
UK
Programming Experience
10+
Edit your post please and use the provided code tags button when posting code on this forum.

Thank you
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
1,959
Location
Chesapeake, VA
Programming Experience
10+
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.
 

beantownace

Member
Joined
Feb 15, 2019
Messages
8
Programming Experience
5-10
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.
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
1,959
Location
Chesapeake, VA
Programming Experience
10+
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.
 

beantownace

Member
Joined
Feb 15, 2019
Messages
8
Programming Experience
5-10
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:
Top Bottom