透過.net 8 來實驗WebApplicationFactory進行整合測試

整合測試

 

為何要使用WebApplicationFactory?

以往筆者都是直接透過呼叫業務邏輯層,來進行測試,這一次實驗使用Microsoft.AspNetCore.Mvc.Testing來調用WebApplicationFactory,直接打API來進行整合測試,以備當作是一個武器。

我直接使用預設的建立一個Web API專案環境.net 8 的WeatherForecastController預設範例寫整合測試。

using Microsoft.AspNetCore.Mvc;

namespace WebApplication1.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }

        [HttpGet(Name = "GetWeatherForecast")]
        public IEnumerable<WeatherForecast> Get()
        {
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }
}

再來Program.cs要設定一下部分類別,方便讓測試專案可以直接指定。

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();
public partial class Program { } // 為了 WebApplicationFactory 以便在測試專案當中能夠使用Program

並測試專案加入專案參考。

然後在測試專案的時候,建立一個測試專案專門跑WeatherForecastControllerTests。

安裝Microsoft.AspNetCore.Mvc.Testing

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc.Testing;

namespace TestProject1
{
    public class WeatherForecastControllerTests
    {
        private WebApplicationFactory<Program> _factory;
        private HttpClient _client;
        [SetUp]
        public void SetUp()
        {
            // 初始化 WebApplicationFactory 及 HttpClient
            _factory = new WebApplicationFactory<Program>();
            _client = _factory.CreateClient();
        }

        [TearDown]
        public void TearDown()
        {
            // 釋放資源
            _client.Dispose();
            _factory.Dispose();
        }

        [Test]
        public async Task GetWeatherForecast_ReturnsSuccessStatusCodeAndData()
        {
            // 發送 GET 請求
            var response = await _client.GetAsync("/WeatherForecast");

            // 確保回應狀態碼為成功
            Assert.That(response.IsSuccessStatusCode, Is.True);

            // 取得回應內容並確認不為空
            var responseString = await response.Content.ReadAsStringAsync();
            Assert.That(responseString, Is.Not.Empty);
        }
    }
}

然後再進行執行整合測試。

結語:這樣未來可以搭配Testcontainers來進行跑整合測試,做為一個備選方案。

元哥的筆記