更方便地模拟 Http 响应
更方便地 Mock Http Response
Intro
在我們的業務代碼中往往會有很多調用內部其他 team 或者是第三方的一些服務,在編寫單元測試代碼時,往往需要 Mock Http Response 來模擬更好可能的返回結果,我封裝了一個簡單的 Http Handler 來簡化 Mock 過程,讓基于 HttpClient Http Response 的模擬更為簡單。
Sample
首先來看一個簡單的使用示例,也是一個測試用例
[Theory] [InlineData(HttpStatusCode.OK)] [InlineData(HttpStatusCode.BadRequest)] [InlineData(HttpStatusCode.Unauthorized)] [InlineData(HttpStatusCode.Forbidden)] [InlineData(HttpStatusCode.NotFound)] [InlineData(HttpStatusCode.InternalServerError)] public?async?Task?HttpStatusTest(HttpStatusCode?httpStatusCode) {var?httpHandler?=?new?MockHttpHandler(req?=>?new?HttpResponseMessage(httpStatusCode));using?var?httpClient?=?new?HttpClient(httpHandler);using?var?response?=?await?httpClient.GetAsync("http://localhost:32123/api/values");Assert.Equal(httpStatusCode,?response.StatusCode); }如果有需要在測試的過程中修改模擬的行為,可以通過 SetResponseFactory 方法來
[Fact] public?async?Task?SetResponseFactoryTest() {var?httpHandler?=?new?MockHttpHandler();using?var?httpClient?=?new?HttpClient(httpHandler);var?response?=?await?httpClient.GetAsync("http://localhost:32123/api/values");Assert.Equal(HttpStatusCode.OK,?response.StatusCode);httpHandler.SetResponseFactory(req?=>?new?HttpResponseMessage(HttpStatusCode.BadRequest));response?=?await?httpClient.GetAsync("http://localhost:32123/api/values");Assert.Equal(HttpStatusCode.BadRequest,?response.StatusCode); }上面的方式都是直接指定了 response,我們也可以根據請求信息動態地返回 response
[Fact] public?async?Task?DynamicResponseTest() {var?httpHandler?=?new?MockHttpHandler(req?=>?new?HttpResponseMessage(HttpStatusCode.OK){Content?=?new?StringContent(req.Method.Method)});using?var?httpClient?=?new?HttpClient(httpHandler);var?response?=?await?httpClient.GetStringAsync("http://localhost:32123/api/values");Assert.Equal(HttpMethod.Get.Method,?response);using?var?httpResponse?=?await?httpClient.PostAsync("http://localhost:32123/api/values",?new?StringContent(""));response?=?await?httpResponse.Content.ReadAsStringAsync();Assert.Equal(HttpMethod.Post.Method,?response); }Implement
實現代碼很簡單,大致如下,根據自定義的邏輯去返回 response 即可
public?sealed?class?MockHttpHandler?:?HttpMessageHandler {private?Func<HttpRequestMessage,?Task<HttpResponseMessage>>?_responseFactory;public?MockHttpHandler()?:?this(_?=>?Task.FromResult(new?HttpResponseMessage(HttpStatusCode.OK))){}public?MockHttpHandler(Func<HttpRequestMessage,?HttpResponseMessage>?responseFactory){Guard.NotNull(responseFactory);_responseFactory?=?req?=>?Task.FromResult(responseFactory(req));}public?MockHttpHandler(Func<HttpRequestMessage,?Task<HttpResponseMessage>>?responseFactory){Guard.NotNull(responseFactory);_responseFactory?=?responseFactory;}public?void?SetResponseFactory(Func<HttpRequestMessage,?HttpResponseMessage>?responseFactory){Guard.NotNull(responseFactory);_responseFactory?=?req?=>?Task.FromResult(responseFactory(req));}public?void?SetResponseFactory(Func<HttpRequestMessage,?Task<HttpResponseMessage>>?responseFactory){Guard.NotNull(responseFactory);_responseFactory?=?responseFactory;}protected?override?Task<HttpResponseMessage>?SendAsync(HttpRequestMessage?request,?CancellationToken?cancellationToken){return?_responseFactory(request);} }More
在需要模擬 Http API 的響應時,可以考慮使用這種方式,希望對你有幫助
最近有幾位小伙伴希望建一個微信交流群,于是建了一個微信群,有需要的小伙伴可以掃描下面的二維碼加群
如果二維碼失效也可以加我微信來加群
References
https://github.com/WeihanLi/WeihanLi.Common/blob/dev/src/WeihanLi.Common/Http/MockHttpHandler.cs
https://github.com/WeihanLi/WeihanLi.Common/blob/dev/test/WeihanLi.Common.Test/HttpTest/MockHttpHandlerTest.cs
總結
以上是生活随笔為你收集整理的更方便地模拟 Http 响应的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C#多线程开发-使用并发集合
- 下一篇: 使用建造者模式创建模拟数据