Question

I'm writing some unit tests for WebAPI controllers, and one of the aspects that I want to assert is that the parameters match.

I've followed the method used in Filip Wojcieszyn's blog, which is working fine, but I'm now looking to extend its assertions.

I have three actions on a controller (all three of which have been verified through actual use):

[HttpGet]
public IEnumerable<Task> Get()

[HttpGet]
public IEnumerable<Task> Get(string elementType)

[HttpGet]
public Task Get(long id)

And I have the following code

var actionSelector = new ApiControllerActionSelector();
var descriptor = actionSelector.SelectAction(_controllerContext);
return descriptor.GetParameters();

The problem is that when I call descriptor.GetParameters() on the parameterless route it returns a collection containing 1 parameter - the "long id" param.

Can anyone explain why it returns only this and neither of the other two overloads, and if it's possible to obtain the overload possibilities?

Was it helpful?

Solution

The cause of the problem was that the route which was being invoked was not specific enough.

  • I had a route which allowed the ID parameter to be optional
  • On the controller are 3 overloads of Get().
  • The Get(long id) action was chosen because although no 'id' parameter was specified, the 'id' parameter is optional and therefore this method fits.

The WebAPI selects the method with the greatest number of matching parameters, which in this case meant that on the line of code

var descriptor = actionSelector.SelectAction(_controllerContext);

An unexpected action was being selected - unexpected because I was looking for Get() and was being given Get(long id).

To solve this I simply split my configured route into two: the first one expects (i.e. non-optional) an 'id' parameter, and a more general route which does not accept an 'id' parameter.

Then everything fell into place.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top