UnitTest ApiController with ExceptionFilterAttribute

I am trying to execute a UnitTest on my controller where the exception is catch byExceptionFilterAttribute and is thrown as an HttpResponseException.

controller

[ExceptionFilters] //ExceptionFilterAttribute
public class EleveController : ApiController
{ 
  private IGpiRepository _gpiRepository;

  public EleveController(IGpiRepository gpiRepository)
  {
     _gpiRepository = gpiRepository;
  }

  [HttpGet]
  [Route("{fiche:int}/grouperepere")]
  public GroupeRepere GroupeRepere(int fiche) //This What Im trying to test
  {
     GpiService service = new GpiService(_gpiRepository);
     return service.Get(fiche); //Throw an ArgumentNullException when fiche == 0
  }
}

      

ExceptionFilter

public class ExceptionFilters : ExceptionFilterAttribute
{
  public override void OnException(HttpActionExecutedContext context)
  {
     if (context.Exception is NotImplementedException)
     {
        context.Response = new HttpResponseMessage(HttpStatusCode.NotImplemented);
     }
     else if (context.Exception is ArgumentNullException)
     {
        context.Response = new HttpResponseMessage(HttpStatusCode.BadRequest)
        {
           Content = new StringContent(string.Format("Argument \"{0}\" is null or invalid", ((ArgumentNullException)context.Exception).ParamName)),
           ReasonPhrase = "Argument null or invalid"
        };
     }
  }

      

and this is my test:

  private IGpiRepository _gpiRepository;
  private Mock<ICallApi> _callApi;
  private EleveController _controller;

  [TestInitialize]
  public void Initialize()
  {
     _callApi = new Mock<ICallApi>();
     _gpiRepository = new GpiRepository(_callApi.Object);
     _controller = new EleveController(_gpiRepository);
  }

  [TestMethod]
  public void EleveController__GroupeRepere_WithBadFiche_400BadRequest()
  {
     string noGroupe = "111";
     int fiche = 0;
     try
     {
        GroupeRepere gp = _controller.GroupeRepere(fiche);

        Assert.Fail();
     }
     catch (Exception e)
     {
        Assert.IsTrue(e is HttpResponseException); // not working --> ArgumentNullException
     }
  }

      

The problem is that there e

is still ArgumentNullException

. When I go to debug it doesn't even reachExceptionFilter class

Am I missing something? Thank.

+3


source to share


1 answer


Your test is directly linked to the controller. ExceptionFilterAttribute

server dependent (remember: attributes Metadata

)

The way to test the behavior is to use an IIS or SelfHost Server , then bring up the server in a test class and submit the request:

[TestInitialize]
public void Initialize()
{
    _callApi = new Mock<ICallApi>();
    _gpiRepository = new GpiRepository(_callApi.Object);

   //initialize your server
   //set _gpiRepository as a dependency and etc..
}
[TestMethod]
public void EleveController__GroupeRepere_WithBadFiche_400BadRequest()
{
    //configure the request
    var result = client.ExecuteAsGet<GroupeRepere>(<your request>);

    Assert.AreEqual(HttpStatusCode.BadRequest,result.StatusCode);
}

      

In my opinion, you shouldn't be wrong if your controller is not different from public Api

(the reason is simple is that such tests are very easy to break, slow and use expensive resources), if your controller besides public Api

you have to test it with Acceptance tests

, then make sure that nothing will change the expected behavior.

If you still want to test this behavior, then I would like to offer you an alternative way to test it:



  • Create UT against ExceptionFilters

    .
  • Create a UT that checks that the method has an attribute ExceptionFilters

For example:

[TestMethod]
public void GroupeRepere_HasExceptionFiltersAttribute()
 {
    var attribute = typeof (UnitTest2).GetMethod("GroupeRepere").GetCustomAttributes(true);

    foreach (var att in attribute)
    {
        if(att.GetType() is typeof(ExceptionFilters))
        {
            return;
        }
    }
    Assert.Fail();
}

      

Pros: It's fast, not easy to break, and doesn't use expensive cutters.

Cons: In production, some customizations may override expected behavior.

+2


source







All Articles