在ASP.NET Core MVC API控制器上对AuthorizeAttribute进行unit testing
我有一个ASP.NET核心MVC API与控制器需要进行unit testing。
控制器:
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System.Threading.Tasks; namespace TransitApi.Api.Controllers { [Route("api/foo")] public class FooController : Controller { private IFooRepository FooRepository { get; } public FooController(IFooRepository fooRepository) { FooRepository = fooRepository; } [HttpGet] [Authorize("scopes:getfoos")] public async Task GetAsync() { var foos = await FooRepository.GetAsync(); return Json(foos); } } }
我必须能够对AuthorizeAttribute
的有效性进行unit testing。 我们的代码库中存在缺少属性和不正确范围的问题。 这个答案正是我正在寻找的,但在Microsoft.AspNetCore.Mvc.Controller
没有ActionInvoker
方法意味着我无法这样做。
unit testing:
[Fact] public void GetAsync_InvalidScope_ReturnsUnauthorizedResult() { // Arrange var fooRepository = new StubFooRepository(); var controller = new FooController(fooRepository) { ControllerContext = new ControllerContext { HttpContext = new FakeHttpContext() // User unfortunately not available in HttpContext //,User = new User() { Scopes = "none" } } }; // Act var result = controller.GetAsync().Result; // Assert Assert.IsType(result); }
如何对没有正确范围的用户进行unit testing,拒绝访问我的控制器方法?
目前我已经决定只测试AuthorizeAttribute
的存在,如下所示,但这真的不够好:
[Fact] public void GetAsync_Analysis_HasAuthorizeAttribute() { // Arrange var fooRepository = new StubFooRepository(); var controller = new FooController(fooRepository) { ControllerContext = new ControllerContext { HttpContext = new FakeHttpContext() } }; // Act var type = controller.GetType(); var methodInfo = type.GetMethod("GetAsync", new Type[] { }); var attributes = methodInfo.GetCustomAttributes(typeof(AuthorizeAttribute), true); // Assert Assert.True(attributes.Any()); }
这需要与内存中测试服务器进行集成测试,因为该属性在框架处理请求管道时由框架进行评估。
ASP.NET Core中的集成测试
集成测试可确保应用程序组件在组装在一起时正常运行。 ASP.NET Core支持使用unit testing框架和内置测试Web主机进行集成测试,可用于处理请求而无需网络开销。
[Fact] public async Task GetAsync_InvalidScope_ReturnsUnauthorizedResult() { // Arrange var server = new TestServer(new WebHostBuilder().UseStartup()); var client = server.CreateClient(); var url = "api/foo"; var expected = HttpStatusCode.Unauthorized; // Act var response = await client.GetAsync(url); // Assert Assert.AreEqual(expected, response.StatusCode); }
如果您不希望测试达到实际的生产实现,您还可以专门为测试创建一个启动,以替换存根/模拟的DI的任何依赖项。
- Docker在VS中运行但在发布到AWS时出错? 错误CS5001:程序不包含适用于入口点的静态“主”方法
- 我应该如何将一个DbContext实例注入IHostedService?
- 如何修复’Microsoft.NETCore.App’,找不到版本’1.1.2’?
- 为什么Scoped服务解析为同一请求的两个不同实例?
- 在部署.net核心应用程序时,HTTP错误500.19,错误代码0x8007000d visual studio 2017
- 在.NET Core中使用Ninject
- 是否可以静默运行.NET Core控制台应用程序(隐藏控制台窗口)?
- 从.NET Core运行PowerShell
- Asp.Net Core:在控制器外部使用内存缓存