.net 什么是编写rest API应用程序集成测试的正确方法?

vof42yt1  于 2022-12-14  发布在  .NET
关注(0)|答案(1)|浏览(128)

我正在寻找一种合适的方法来为我的纯REST API应用程序编写集成测试。我还没有任何UI,只有数据库和控制器。我通过Postman发送请求。我发现了一些关于这个主题的材料:https://timdeschryver.dev/blog/how-to-test-your-csharp-web-api#a-custom-and-reusable-xunit-fixture https://code-maze.com/aspnet-core-integration-testing/https://www.codingame.com/playgrounds/35462/creating-web-api-in-asp-net-core-2-0/part-3---integration-tests。每种方法都有一些不同,有一些额外的类等等。我编写了一个简单的测试,如下所示:

public class BasicTests
: IClassFixture<WebApplicationFactory<Program>>
{
    private readonly WebApplicationFactory<Program> _factory;

    public BasicTests(WebApplicationFactory<Program> factory)
    {
        _factory = factory;
    }

    [Theory]
    [InlineData("http://localhost:5126/api/Categories")]
    [InlineData("http://localhost:5126/api/Categories/88624B65-EF01-4463-79D4-08DAA478AD6E")]
    public async Task Get_EndpointsReturnSuccessAndCorrectContentType(string url)
    {
        // Arrange
        var client = _factory.CreateClient();

        // Act
        var response = await client.GetAsync("http://localhost:5126/api/FinancialOperations");

        // Assert
        response.EnsureSuccessStatusCode(); // Status Code 200-299
        Assert.Equal("application/json; charset=utf-8",
            response.Content.Headers.ContentType.ToString());
    }
}

我希望所有的测试都能这么简单,但是我不知道如何像这样测试POST/PUT/DELETE。不管怎样,有人能分享一个为纯rest API应用程序编写集成测试的正确方法吗?我的CatogoryContoller示例(部分)

[HttpGet]
    public async Task<ActionResult<IEnumerable<CategoryDTO>>> GetCategories()
    {
        _logger.LogInformation("Getting all categories.");
        var categoriesDTO = new List<CategoryDTO>();
        var categories = await _context.Categories
            .ToListAsync();
        if (categories == null)
        {
            _logger.LogError("No categories were found in current context.");
            return NotFound();
        }
        foreach (var category in categories)
        {
            categoriesDTO.Add(_mapper.Map<CategoryDTO>(category));
        }

        _logger.LogInformation("GetIncomes method execudeted successfully, and the list of DTO returned.");

        return categoriesDTO;
    }

    [HttpGet("{id}")]
    public async Task<ActionResult<CategoryDTO>> GetCategory(Guid id)
    {
        _logger.LogInformation($"Getting operation by {id} id in GetCategory method.");
        var category = await _context.Categories
            .Where(x => x.Id == id)
            .FirstOrDefaultAsync();
        if (category == null)
        {
            _logger.LogError($"Category {id} was not found in the current context.");
            return NotFound($"Category Id: {id}");
        }

        var categoryDTO = _mapper.Map<CategoryDTO>(category);

        _logger.LogInformation($"GetCategory method execudeted successfully, and the id: {id} category returned.");

        return categoryDTO;
    }

    [HttpPut("{id}")]
    public async Task<ActionResult> PutCategory(Guid id, CategoryDTO categoryDTO)
    {
        var category = _context.Categories.FirstOrDefault(x => x.Id == id);
        if (category == null)
        {
            _logger.LogError($"Update category id: {id} was not found.");
            return NotFound();
        }

        _mapper.Map<CategoryDTO, Category>(categoryDTO, category);
        _context.Entry(category).State = EntityState.Modified;

        try
        {
            _logger.LogInformation($"Trying to save updated category {id} into the Database.");
            await _context.SaveChangesAsync();
            _logger.LogInformation($"Updated category id: {id} saved into the Database successfully.");
        }
        catch (DbUpdateConcurrencyException ex)
        {
            if (!CategoryExists(id))
            {
                _logger.LogError($"Category id: {id} does not exist.");
                return NotFound($"Category id: {id}");
            }
            else
            {
                _logger.LogError(ex.Message);
                return BadRequest(new { message = ex.Message });
            }
        }
        return NoContent();
    }
erhoui1w

erhoui1w1#

您应该使用httpClient并将请求发送到该API地址,然后Assert该响应

var dataDictionary = new Dictionary<string, string>()
        {
            { "Name",name},
            { "Job",job},
            { "Age",age}
        };
        var httpContent = new FormUrlEncodedContent(dataDictionary);

        var httpClientObj=new httpClient();
        var request = await httpClientObj.PostAsync(url,httpContent);
        
        request.EnsureSuccessStatusCode();
        var responseObjectContainer = request.Deserialize();
        Assert.True(responseObjectContainer?.Count > 0);

相关问题