DEV Community

Kim CH
Kim CH

Posted on

.NET: Integration Test for uploading csv/excel file via HttpClient

Suppose that we have 2 APIs to import the list of codes - one uses a CSV template, and the other uses an Excel template. Please note that saving data isn't included; I'm just showing how to test posting CSV/Excel files.

The following packages have been used

[ApiController]
public class ImportProductsController : ControllerBase
{

    [HttpPost("/products/import-csv")]
    [ProducesResponseType<List<ImportProductModel>>(StatusCodes.Status200OK)]
    public IActionResult DoImportCsv(IFormFile file)
    {
        using var stream = file.OpenReadStream();
        using var reader = new StreamReader(stream);
        using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);
        csv.Context.RegisterClassMap<ClassMapImportProductModel>();
        var records = csv.GetRecords<ImportProductModel>().ToList();
        return Ok(records);
    }

    [HttpPost("/products/import-excel")]
    [ProducesResponseType<List<ImportProductModel>>(StatusCodes.Status200OK)]
    public IActionResult DoImportExcel([FromForm] IFormFile file)
    {
        var records = new ExcelMapper(file.OpenReadStream()) { HeaderRow = true }.Fetch<ImportProductModel>();
        return Ok(records.ToList());
    }
}
Enter fullscreen mode Exit fullscreen mode

Test import CSV

[Fact]
public async Task TestImportByCsv()
{
    // ==================================
    // Step-01: Generate the CSV stream
    // ==================================
    var sb = new StringBuilder().AppendLine("Product Code,Product Name");

    var numberOfProducts = 10;
    for (int i = 0; i < numberOfProducts; i++)
    {
        sb.AppendLine(string.Join(",", [
            this._faker.Random.AlphaNumeric(10).ToUpper(),
                this._faker.Commerce.ProductName()
            ]));
    }

    var csvBytes = Encoding.UTF8.GetBytes(sb.ToString());
    var csvStream = new MemoryStream(csvBytes);

    // ==================================
    // Step-02: Prepare the FormData
    // ==================================
    using var formData = new MultipartFormDataContent();
    formData.Add(new StreamContent(csvStream), name: "file", fileName: "abc.csv");

    // ==================================
    // Step-03: Execute the POST request
    // ==================================
    var httpClient = this._factory.CreateClient();
    var response = await httpClient.PostAsync("/products/import-csv", formData);
    response.StatusCode.ShouldBe(HttpStatusCode.OK);

    var products = await this.ParseResponse<List<ImportProductModel>>(response);

    products.ShouldNotBeEmpty();
    products.Count.ShouldBe(numberOfProducts);
    products.ForEach(p =>
    {
        p.Code.ShouldNotBeNullOrWhiteSpace();
        p.Name.ShouldNotBeNullOrWhiteSpace();
    });
}
Enter fullscreen mode Exit fullscreen mode

Test import Excel file

[Fact]
public async Task TestImportViaExcel()
{
    // ==================================
    // Step-01: Generate the Excel stream
    // ==================================
    var workBook = new XSSFWorkbook();
    var sheet = workBook.CreateSheet("Sheet1");
    var headerRow = sheet.CreateRow(0);
    headerRow.CreateCell(0).SetCellValue("Product Code");
    headerRow.CreateCell(1).SetCellValue("Product Name");

    const int numberOfProducts = 10;
    for (int i = 1; i <= numberOfProducts; i++)
    {
        var dataRow = sheet.CreateRow(i);
        dataRow.CreateCell(0).SetCellValue(this._faker.Random.AlphaNumeric(10).ToUpper());
        dataRow.CreateCell(1).SetCellValue(this._faker.Commerce.ProductName());
    }

    var excelStream = new MemoryStream();
    workBook.Write(excelStream, leaveOpen: true);

    // ==================================
    // Step-02: Prepare the FormData
    // ==================================
    using var formData = new MultipartFormDataContent();
    formData.Add(content: new StreamContent(excelStream),
                name: "file",
                fileName: "abc.excel");

    // ==================================
    // Step-03: Execute the POST request
    // ==================================
    var httpClient = this._factory.CreateClient();
    var response = await httpClient.PostAsync("/products/import-excel", formData);
    response.StatusCode.Should().Be(HttpStatusCode.OK);

    var products = await this.ParseResponse<List<ImportProductModel>>(response);
    products.ShouldNotBeEmpty();
    products.Count.ShouldBe(numberOfProducts);
    products.ForEach(p =>
    {
        p.Code.ShouldNotBeNullOrWhiteSpace();
        p.Name.ShouldNotBeNullOrWhiteSpace();
    });
}
Enter fullscreen mode Exit fullscreen mode

Thanks for reading!!!
The full example can be found at my repo on GitHub - setup-dotnet-test-projects

Top comments (0)