2
2
using System . Net . Http ;
3
3
using System . Threading . Tasks ;
4
4
5
- using Moq ;
5
+ using Microsoft . AspNetCore . Builder ;
6
+ using Microsoft . AspNetCore . Hosting ;
7
+ using Microsoft . AspNetCore . Http ;
8
+ using Microsoft . AspNetCore . TestHost ;
9
+ using Microsoft . Extensions . DependencyInjection ;
10
+ using Microsoft . Extensions . Hosting ;
11
+
12
+ using NFluent ;
13
+
14
+ using TestableHttpClient . NFluent ;
6
15
7
16
using Xunit ;
8
17
@@ -17,58 +26,102 @@ public async Task ConfigureIHttpClientFactoryToUseTestableHttpClient()
17
26
var testableHttpMessageHandler = new TestableHttpMessageHandler ( ) ;
18
27
testableHttpMessageHandler . RespondWith ( response => response . WithHttpStatusCode ( HttpStatusCode . OK ) ) ;
19
28
20
- // Create a mock for IHttpClientFactory
21
- var httpClientFactoryMock = new Mock < IHttpClientFactory > ( ) ;
22
- // Setup the CreateClient method to use the testableHttpMessageHandler
23
- httpClientFactoryMock . Setup ( x => x . CreateClient ( It . IsAny < string > ( ) ) ) . Returns ( new HttpClient ( testableHttpMessageHandler ) ) ;
29
+ var services = new ServiceCollection ( ) ;
30
+ // Register an HttpClient and configure the TestableHttpMessageHandler as the PrimaryHttpMessageHandler
31
+ services . AddHttpClient ( string . Empty ) . ConfigurePrimaryHttpMessageHandler ( ( ) => testableHttpMessageHandler ) ;
24
32
25
- // Pass the mocked IHttpClientFactory to the class under test.
26
- var client = new HttpbinClient ( httpClientFactoryMock . Object ) ;
27
- var result = await client . Get ( ) ;
33
+ var serviceProvider = services . BuildServiceProvider ( ) ;
28
34
29
- Assert . Equal ( HttpStatusCode . OK , result . StatusCode ) ;
35
+ // Request the IHttpClientFactory
36
+ var httpClientFactory = serviceProvider . GetRequiredService < IHttpClientFactory > ( ) ;
37
+ // Create the HttpClient
38
+ var client = httpClientFactory . CreateClient ( ) ;
39
+ // And use it...
40
+ _ = await client . GetAsync ( "https://httpbin.com/get" ) ;
41
+
42
+ // Now use the assertions to make sure the request was actually made.
30
43
testableHttpMessageHandler . ShouldHaveMadeRequestsTo ( "https://httpbin.com/get" ) ;
31
44
}
32
45
33
46
[ Fact ]
34
- public async Task ConfigureMultiplehttpClientFactories ( )
47
+ public async Task ConfigureMultipleHttpMessageHandlers ( )
35
48
{
49
+ // Create multiple TestableHttpMessageHandlers as usual, if the response is not important, a single TestableHttpMessageHandler can be used.
36
50
var testableGithubHandler = new TestableHttpMessageHandler ( ) ;
37
51
testableGithubHandler . RespondWith ( response => response . WithHttpStatusCode ( HttpStatusCode . OK ) . WithResponseHeader ( "Server" , "github" ) ) ;
38
52
39
53
var testableHttpBinHandler = new TestableHttpMessageHandler ( ) ;
40
54
testableHttpBinHandler . RespondWith ( response => response . WithHttpStatusCode ( HttpStatusCode . NotFound ) . WithResponseHeader ( "Server" , "httpbin" ) ) ;
41
55
42
- // Create a mock for IHttpClientFactory
43
- var httpClientFactoryMock = new Mock < IHttpClientFactory > ( ) ;
44
- // Setup the CreateClient method to use the testableHttpMessageHandler
45
- httpClientFactoryMock . Setup ( x => x . CreateClient ( "github" ) ) . Returns ( new HttpClient ( testableGithubHandler ) ) ;
46
- httpClientFactoryMock . Setup ( x => x . CreateClient ( "httpbin" ) ) . Returns ( new HttpClient ( testableHttpBinHandler ) ) ;
56
+ var services = new ServiceCollection ( ) ;
57
+ // Register named HttpClients and configure the correct TestableHttpMessageHandler as the PrimaryHttpMessageHandler
58
+ services . AddHttpClient ( "github" ) . ConfigurePrimaryHttpMessageHandler ( ( ) => testableGithubHandler ) ;
59
+ services . AddHttpClient ( "httpbin" ) . ConfigurePrimaryHttpMessageHandler ( ( ) => testableHttpBinHandler ) ;
60
+ var serviceProvider = services . BuildServiceProvider ( ) ;
47
61
48
- var httpClientFactory = httpClientFactoryMock . Object ;
62
+ // Request the IHttpClientFactory
63
+ var httpClientFactory = serviceProvider . GetRequiredService < IHttpClientFactory > ( ) ;
49
64
65
+ // Create the named HttpClient
50
66
var githubClient = httpClientFactory . CreateClient ( "github" ) ;
51
- await githubClient . GetAsync ( "https://github.com/api/users" ) ;
67
+ // And use it.
68
+ var result = await githubClient . GetAsync ( "https://github.com/api/users" ) ;
69
+ Check . That ( result ) . HasResponseHeader ( "Server" , "github" ) . And . HasHttpStatusCode ( HttpStatusCode . OK ) ;
52
70
71
+ // Create another named HttpClient
53
72
var httpbinClient = httpClientFactory . CreateClient ( "httpbin" ) ;
54
- await httpbinClient . GetAsync ( "https://httpbin.com/get" ) ;
73
+ // And use it...
74
+ result = await httpbinClient . GetAsync ( "https://httpbin.com/get" ) ;
75
+ Check . That ( result ) . HasResponseHeader ( "Server" , "httpbin" ) . And . HasHttpStatusCode ( HttpStatusCode . NotFound ) ;
76
+
77
+ // Now assert every TestableHttpMessageHandlers to make sure we made the requests.
78
+ testableGithubHandler . ShouldHaveMadeRequestsTo ( "https://github.com/*" ) ;
79
+ testableHttpBinHandler . ShouldHaveMadeRequestsTo ( "https://httpbin.com/*" ) ;
80
+ }
81
+
82
+ [ Fact ]
83
+ public async Task ConfigureViaConfigureTestServicesOnHostBuilder ( )
84
+ {
85
+ // Create TestableHttpMessageHandler as usual.
86
+ var testableHttpMessageHandler = new TestableHttpMessageHandler ( ) ;
87
+ testableHttpMessageHandler . RespondWith ( response => response . WithHttpStatusCode ( HttpStatusCode . OK ) ) ;
55
88
56
- testableGithubHandler . ShouldHaveMadeRequests ( ) ;
57
- testableHttpBinHandler . ShouldHaveMadeRequests ( ) ;
89
+ // Setup a TestServer
90
+ using var host = await new HostBuilder ( )
91
+ . ConfigureWebHost ( webBuilder =>
92
+ {
93
+ webBuilder . UseTestServer ( )
94
+ // Configure the startup class, in this case it already configures a default HttpClient
95
+ . UseStartup < StartUpWithDefaultHttpHandler > ( )
96
+ // Reconfigure the default HttpClient and set the TestableHttpMessageHandler as the primary HttpMessageHandler
97
+ . ConfigureTestServices ( services => services . AddHttpClient ( string . Empty ) . ConfigurePrimaryHttpMessageHandler ( ( ) => testableHttpMessageHandler ) ) ;
98
+ } )
99
+ . StartAsync ( ) ;
100
+
101
+ var client = host . GetTestClient ( ) ;
102
+ // Make a request to the testserver
103
+ _ = await client . GetAsync ( "/" ) ;
104
+
105
+ // Assert that the code in the test server made the expected request.
106
+ testableHttpMessageHandler . ShouldHaveMadeRequestsTo ( "https://httpbin.com/get" ) ;
58
107
}
59
108
60
- private class HttpbinClient
109
+ private class StartUpWithDefaultHttpHandler
61
110
{
62
- private readonly IHttpClientFactory _httpClientFactory ;
63
- public HttpbinClient ( IHttpClientFactory httpClientFactory )
111
+ public static void ConfigureServices ( IServiceCollection services )
64
112
{
65
- _httpClientFactory = httpClientFactory ;
113
+ services . AddHttpClient ( ) ;
66
114
}
67
115
68
- public Task < HttpResponseMessage > Get ( )
116
+ public static void Configure ( IApplicationBuilder app )
69
117
{
70
- var client = _httpClientFactory . CreateClient ( ) ;
71
- return client . GetAsync ( "https://httpbin.com/get" ) ;
118
+ app . Run ( async context =>
119
+ {
120
+ var httpClientFactory = context . RequestServices . GetRequiredService < IHttpClientFactory > ( ) ;
121
+ var httpClient = httpClientFactory . CreateClient ( ) ;
122
+ await httpClient . GetAsync ( "https://httpbin.com/get" ) ;
123
+ await context . Response . WriteAsync ( "Hello" ) ;
124
+ } ) ;
72
125
}
73
126
}
74
127
}
0 commit comments