使用.NET Core和NUnit进行集成测试

4

我有一个控制器正在接收 JWT 声明,如果声明正确,则返回如下格式的类别 Json 字符串:

[Authorize(Policy = "OnlyValidUsers")]
[Route("api/[controller]")]
public class CategoriesController : Controller
{
    private readonly IGenericService<Category> _categoriesService;

    public CategoriesController(IGenericService<Category> categoriesService)
    {
        _categoriesService = categoriesService;
    }

    [Authorize(Policy = "GenericUser")]
    [HttpGet("/api/Categories/Get", Name = "GetCategories")]
    public async Task<IActionResult> Get()
    {
        var categories = await _categoriesService.GetAll();
        return Json(categories);
    }
}

这是在用户登录我的系统并获取了一个承载令牌后发生的。
我正在尝试通过以下方式在集成测试中对其进行测试:-
[TestFixture]
public class CategoriesControllerIntegrationTests
{
    private HttpClient _client;
    private Category _testCategory;
    private string _request;

    [SetUp]
    public void Setup()
    {
        var basePath = PlatformServices.Default.Application.ApplicationBasePath;
        var projectPath = Path.GetFullPath(Path.Combine(basePath, "../../../../SportsStore.Tests"));

        var server = new TestServer(Utils.GetHostBuilder(new string[] { })
            .UseContentRoot(projectPath)
            .UseEnvironment("Development")
            .UseStartup<Startup>());

        _client = server.CreateClient();
        _testCategory = new Category
        {
            Name = Enums.GetEnumDescription(Enums.CategoryTestData.Name)
        };
        _request = Enums.GetEnumDescription(Enums.Requests.Categories);
    }

    [Test]
    public async Task Get_ReturnsAListOfCategories_CategoriesController()
    {
        var response = await _client.GetAsync(_request + "Get");
        response.EnsureSuccessStatusCode();

        Assert.IsTrue(true);
    }

Utils类的代码如下:
public class Utils
{
    public static IWebHostBuilder GetHostBuilder(string[] args)
    {
        var config = new ConfigurationBuilder()
                   .AddCommandLine(args)
                   .AddEnvironmentVariables(prefix: "ASPNETCORE_")
                   .Build();

        return new WebHostBuilder()
            .UseConfiguration(config)
            .UseKestrel()
            .UseStartup<Startup>();
    }
}

当我运行测试时,出现了预期的401(未授权)错误。如何使此测试通过?如何在测试中传递声明以验证其是否有效?
另外,如果我删除[Authorize]过滤器,仍然会收到401(未授权)错误,我认为这不应该发生。
非常感谢任何帮助!
谢谢

你移除了两个 Authrize 过滤器吗?因为我看到有两个(并且你是否指定了更多的全局过滤器)?要么确保在测试中通过提供正确的 cookie 状态(例如首先登录)传递授权属性,要么在策略中进行覆盖(但这可能会使您以后容易受到攻击)。 - Joel Harkes
我之前已经将它们删除了,只是为了检查它们是否是原因,但是当我删除它们时,我仍然得到了401错误,这就是为什么我怀疑我的Setup.cs或TestServer中有一些问题的原因。 - JMon
确认问题出在以下代码处: services.AddMvc(config => { var policy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .Build(); config.Filters.Add(new AuthorizeFilter(policy)); }); - JMon
我建议使用不同的Startup.cs进行测试,并进行不同的AddMvc。或者通过解析SignInManager等使单元测试首先登录。不要用if else更改默认的startup.cs,这只会导致安全风险。 - Joel Harkes
我在考虑创建一个独立的Startup.cs文件,但是我仍然需要测试策略,例如“GenericUser”和“Administrator”,因此我仍然需要一种将这些策略传递给API的方法。 - JMon
显示剩余2条评论
1个回答

2
您可以为http客户端的每个请求添加Authorization头:
_client = server.CreateClient();
_client .DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "VALID JWT goes here");

这样,您就不需要为测试和实际环境进行单独的配置。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接