WeatherForecastControllerTests.cs

進行 .net core xUnit 的整合測試時,我們通常會使用 WebApplicationFactory.cs來模擬整個應用程序的啟動和運行。由於測試中經常需要自定義
HTTP Header,因此可以通過實現一個簡單實作DelegatingHandler.cs來記錄請求和回應的詳細信息。也讓執行整合測試的請求與回應可以輸出到
xUnit 中的 Console視窗。


  • WeatherForecastControllerTests.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

public class WeatherForecastControllerTests : IClassFixture<TestWebApplicationFactory<Program>>
{
public WeatherForecastControllerTests(TestWebApplicationFactory<Program> factory,
ITestOutputHelper testOutputHelper)
{
TestOutputHelper = testOutputHelper;
HttpClient = factory.CreateDefaultClient(new HttpClientLogger(TestOutputHelper));
}

private ITestOutputHelper TestOutputHelper { get; }

private HttpClient HttpClient { get; }

[Fact]
public async Task Test_GetWeatherForecast_ReturnsValidForecasts()
{
// arrange
var requestUri = "/WeatherForecast";

// act
var response = await HttpClient.GetAsync(requestUri);

// assert
response.Should().Be200Ok()
.And
.Satisfy<List<WeatherForecast>>(w => w.Should().HaveCount(5));
}
}

  • ITestOutputHelper.cs 是xUnit可以將一些訊息輸出的類別。以下是 HttpClientLogger.cs 只是將 Request Response 顯示出來,還有這隻
    API 大約花費時間。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

public class HttpClientLogger : DelegatingHandler
{
private readonly ITestOutputHelper _testOutputHelper;

public HttpClientLogger(ITestOutputHelper testOutputHelper)
{
_testOutputHelper = testOutputHelper;
}

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
await LogHttpRequestAsync(request);

var stopwatch = Stopwatch.StartNew();

var response = await base.SendAsync(request, cancellationToken);

stopwatch.Stop();

await LogHttpResponseAsync(response, stopwatch.Elapsed);

return response;
}

private async Task LogHttpRequestAsync(HttpRequestMessage request)
{
_testOutputHelper.WriteLine($"Request Method: {request.Method}");
_testOutputHelper.WriteLine($"Request URL: {request.RequestUri}");
foreach (var header in request.Headers)
{
_testOutputHelper.WriteLine($"Request Header: {header.Key} - {string.Join(", ", header.Value)}");
}
if (request.Content != null)
{
var content = await request.Content.ReadAsStringAsync();
_testOutputHelper.WriteLine($"Request Content: {content}");
}
}

private async Task LogHttpResponseAsync(HttpResponseMessage response, TimeSpan duration)
{
_testOutputHelper.WriteLine($"Response Http Code: {response.StatusCode}");
_testOutputHelper.WriteLine($"Response Time: {duration.TotalMilliseconds} ms");

foreach (var header in response.Headers)
{
_testOutputHelper.WriteLine($"Response Header: {header.Key} - {string.Join(", ", header.Value)}");
}
var content = await response.Content.ReadAsStringAsync();
_testOutputHelper.WriteLine($"Response Content: {content}");
}
}

執行之後 可以在測試中的Console畫面看到以下資訊。

xUnit_HttpClientLogger

這樣跑測試時,可以看到每隻API的 Http Request Response相關資訊。