You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 6控制器Action方法测试:正确传递路径与查询参数

正确传递.NET 6控制器HttpGet的路径与查询参数

问题背景

你需要测试的HttpGet Action包含路径参数endDate、client,以及查询参数creationDate、字符串数组portfolios和可选布尔参数includeGeneric。当前测试代码因参数传递方式错误无法运行,以下是修正方案:

原Action方法代码

[HttpGet("Date/{endDate}/client/{client}")]
public IActionResult GetClient(
    DateTime endDate,
    string client,
    [FromQuery] DateTime creationDate,
    [FromQuery] string[] portfolios,
    [FromQuery] bool includeGeneric = false)
{
    var result = new List<Portfolio>();
    var param = new PortfoliosParams(portfolios, new[] { client }, endDate, creationDate);

    var portfolios = this.repository.GetPortfolios(param);
    result.AddRange(portfolios);

    var portfolioRepository = this.portfolioRepository.GetPortfolioRepository(param);
    result.AddRange(portfolioRepository);

    var params = new PortfoliosParams(portfolios, new[] { Helpers.ClientName }, endDate, creationDate);

    var genericPortfolios = this.repository.GetPortfolios(params);
     result.AddRange(genericPortfolios);

     var genericPortfoliosRepository = this.portfolioRepository.GetPortfolioRepository(params);
     result.AddRange(genericPortfoliosRepository);
     return this.Ok(result);
}

原测试代码的核心问题

  1. 路径占位符{endDate}、{client}未被实际值替换,直接作为静态字符串传递
  2. 查询参数creationDate、portfolios未拼接到URL的查询字符串中
  3. GetAsync方法参数传递逻辑错误,该方法不支持自动将多参数拼接为URL
  4. 断言逻辑错误:GetAsync返回的是HttpResponseMessage对象,无法直接断言等于数值3

修正后的测试代码

[Test]
public async Task GetPortfolios()
{
    var clientName = "TEST";
    var creationDate = new DateTime(2023, 5, 1);
    var endDate = new DateTime(2024, 1, 1);
    var portfolios = new[] { "TEST1", "TEST2", "TEST3" };

    var server = TestHelpers.CreateTestServer();
    var httpClient = server.CreateClient();

    // 1. 替换路径参数,DateTime使用ISO 8601格式确保路由绑定成功
    var basePath = $"api/Portfolios/Date/{endDate:yyyy-MM-dd}/client/{clientName}";

    // 2. 构建查询字符串,自动处理URL编码
    var queryBuilder = new QueryString();
    queryBuilder = queryBuilder.Add("creationDate", creationDate.ToString("yyyy-MM-dd"));
    // 数组参数采用重复key的形式(ASP.NET Core默认支持该绑定方式)
    foreach (var portfolio in portfolios)
    {
        queryBuilder = queryBuilder.Add("portfolios", portfolio);
    }
    // 可选参数includeGeneric默认是false,若需传true则取消下方注释
    // queryBuilder = queryBuilder.Add("includeGeneric", "true");

    // 3. 拼接完整请求URL
    var requestUrl = basePath + queryBuilder;

    // 4. 发送请求并验证响应状态
    var response = await httpClient.GetAsync(requestUrl);
    response.EnsureSuccessStatusCode();

    // 5. 读取响应内容并执行断言
    var result = await response.Content.ReadFromJsonAsync<List<Portfolio>>();
    Assert.That(result.Count, Is.EqualTo(3));
}

public static class TestHelpers
{
    private static WebApplicationFactory<Program> testServer;

    public static WebApplicationFactory<Program> CreateTestServer()
    {
        if (testServer != null)
        {
            return testServer;
        }

        return testServer =
            new WebApplicationFactory<Program>()
                .WithWebHostBuilder(builder =>
                    builder
                        .UseContentRoot(Directory.GetCurrentDirectory()));
    }
}

关键注意事项

  • 路径参数处理:必须直接替换URL中的占位符,DateTime需使用控制器可正确绑定的格式(推荐ISO 8601)
  • 查询数组参数:ASP.NET Core默认支持portfolios=TEST1&portfolios=TEST2的重复key形式,无需额外配置
  • 查询字符串拼接:使用QueryString类可避免手动拼接时的URL编码错误
  • 响应断言:需先确保请求成功,再将响应内容反序列化为实体类后,针对实体属性执行断言

内容的提问来源于stack exchange,提问作者Garry A

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 00:07:01