我在使用Owin TestServer模拟ApiController
的动作过滤器时遇到问题。
基本上,总是使用实际的实现方式,而不是模拟的实现方式。
运行测试时,使用真实的CustomAuthorizationFilter
。
我正在寻找的是能够模拟该实现,以测试异常过滤器的行为以及授权异常发生时整个控制器的响应。
我想念什么?
[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class CustomAuthorizationFilter : AuthorizationFilterAttribute
{
public override async Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
{
// For the sake of simplicity I'm throwing an exception
// Real code calls to an internal identity provider
throw new NotImplementedException();
}
}
[HttpGet]
[Route("")]
[CustomAuthorizationFilter]
public async Task<IHttpActionResult> GetAsync()
{
return Ok();
}
[TestMethod]
public async Task TestSomething()
{
var testServer = CreateTestServer();
var actualResponse = await testServer.HttpClient.GetAsync("");
//Assertions
}
protected TestServer CreateTestServer()
{
Func<IFilter, IFilter> filterProvider = (instance) =>
{
//This is not working, the real implementation is the one being executed
var filter = A.Fake<AuthorizationFilterAttribute>();
A.CallTo(() => filter.OnAuthorizationAsync(A<HttpActionContext>.Ignored, A<CancellationToken>.Ignored)).Throws<UnauthorizedAccessException>();
return filter;
};
var testServer = TestServer.Create(app =>
{
var config = new HttpConfiguration();
config.Services.Replace(typeof(IAssembliesResolver), new TestWebApiResolver(typeof(MyController)));
WebApiConfig.Register(config);
config.Services.Add((typeof(IFilterProvider)), new DelegateFilterProvider(filterProvider));
app.UseWebApi(config);
});
testServer.BaseAddress = new Uri("http://localhost/");
return testServer;
}
internal class DelegateFilterProvider : IFilterProvider
{
private readonly Func<IFilter, IFilter> filterProvider;
public DelegateFilterProvider(Func<IFilter, IFilter> filterProvider)
{
this.filterProvider = filterProvider;
}
public IEnumerable<FilterInfo> GetFilters(HttpConfiguration configuration, HttpActionDescriptor actionDescriptor)
{
var actionFilters = actionDescriptor.GetFilters().Select(instance =>
{
// This is where the Filter
var filter = filterProvider(instance);
var result = new FilterInfo(filter, FilterScope.Action);
return result;
});
return actionFilters;
}
}
<package id="Microsoft.AspNet.WebApi" version="5.2.6" targetFramework="net472" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.6" targetFramework="net472" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.6" targetFramework="net472" />
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.6" targetFramework="net472" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.6" targetFramework="net472" />
<package id="Microsoft.Owin" version="4.0.0" targetFramework="net472" />
<package id="Microsoft.Owin.Hosting" version="4.0.0" targetFramework="net472" />
<package id="Microsoft.Owin.Testing" version="4.0.0" targetFramework="net472" />
<package id="Owin" version="1.0" targetFramework="net472" />