I'm using ThinkTecture's resource based authorization in my WebApi.
I'm trying to test one of my controller that I needed to check the access inside the function. But now, I can't test the function anymore since, I can't mock an extension method and since it's a nuget method, I can't modify the class to inject another value.
My controller look like this:
public class AlbumController : ApiController
{
public async Task<IHttpActionResult> Get(int id)
{
if (!(await Request.CheckAccessAsync(ChinookResources.AlbumActions.View,
ChinookResources.Album,
id.ToString())))
{
return this.AccessDenied();
}
return Ok();
}
}
And the ResourceAuthorizationManager is setted into the startup like this:
app.UseResourceAuthorization(new ChinookAuthorization());
Source code of the ThinkTecture project is here.
Thank you for your help
The ResourceAuthorizationAttribute uses Reqest.CheckAccess so I don't think it is a good solution to abstract away the implementation and then injecting it into the controller since in theory, the ResourceAuthorizationAttribute and the created service could use different implementations of the CheckAccess method.
I took a simpler approach by creating a BaseController
public class BaseController : ApiController
{
public virtual Task<bool> CheckAccessAsync(string action, params string[] resources)
{
return Request.CheckAccessAsync(action, resources);
}
}
and making CheckAccessAsync virtual so I can mock it (by for example Moq).
then from my controller
public class AlbumController : BaseController
{
public async Task<IHttpActionResult> Get(int id)
{
if (!(await CheckAccessAsync(ChinookResources.AlbumActions.View,
ChinookResources.Album,
id.ToString())))
{
return this.AccessDenied();
}
return Ok();
}
}
Unit testing the controller then is as easy as:
[TestClass]
public class TestClass
{
Mock<AlbumController> mockedTarget
AlbumController target
[TestInitialize]
public void Init()
{
mockedTarget = new Mock<AlbumController>();
target = mockedTarget.Object;
}
[Test]
public void Test()
{
mockedTarget.Setup(x => x.CheckAccessAsync(It.IsAny<string>(),
It.IsAny<string[]>()))
.Returns(Task.FromResult(true));
var result = target.Get(1);
// Assert
}
}