Development Tip

.NET 테스트에서 모의 ​​HttpClient를 전달하는 방법은 무엇입니까?

yourdevel 2021. 1. 6. 20:31
반응형

.NET 테스트에서 모의 ​​HttpClient를 전달하는 방법은 무엇입니까?


Microsoft.Net.Http일부 Json데이터 를 검색 하는 데 사용하는 서비스가 있습니다. 큰!

물론 내 단위 테스트가 실제 서버에 부딪히는 것을 원하지 않습니다 (그렇지 않으면 통합 테스트).

다음은 내 서비스 ctor입니다 (종속성 주입을 사용합니다 ...)

public Foo(string name, HttpClient httpClient = null)
{
...
}

이걸 어떻게 조롱 할 수 있을지 모르겠네요 .. .. Moq또는 FakeItEasy.

내 서비스가 전화를 걸 GetAsync거나 PostAsync.. 그 전화를 가짜 로 만들 수 있는지 확인하고 싶습니다 .

어떻게 할 수 있습니까?

나는 내 자신의 래퍼를 만들 필요가 없다. .. 그게 쓰레기니까 :( 마이크로 소프트가 이것에 대해 감독을 할 수 없었지?

(예, 래퍼를 만드는 것은 쉽습니다 .. 전에 해본 적이 있지만 그게 요점입니다!)


핵심 HttpMessageHandler를 가짜로 바꿀 수 있습니다. 다음과 같은 것 ...

public class FakeResponseHandler : DelegatingHandler
    {
        private readonly Dictionary<Uri, HttpResponseMessage> _FakeResponses = new Dictionary<Uri, HttpResponseMessage>(); 

        public void AddFakeResponse(Uri uri, HttpResponseMessage responseMessage)
        {
                _FakeResponses.Add(uri,responseMessage);
        }

        protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
        {
            if (_FakeResponses.ContainsKey(request.RequestUri))
            {
                return _FakeResponses[request.RequestUri];
            }
            else
            {
                return new HttpResponseMessage(HttpStatusCode.NotFound) { RequestMessage = request};
            }

        }
    }

그런 다음 가짜 핸들러를 사용할 클라이언트를 만들 수 있습니다.

var fakeResponseHandler = new FakeResponseHandler();
fakeResponseHandler.AddFakeResponse(new Uri("http://example.org/test"), new HttpResponseMessage(HttpStatusCode.OK));

var httpClient = new HttpClient(fakeResponseHandler);

var response1 = await httpClient.GetAsync("http://example.org/notthere");
var response2 = await httpClient.GetAsync("http://example.org/test");

Assert.Equal(response1.StatusCode,HttpStatusCode.NotFound);
Assert.Equal(response2.StatusCode, HttpStatusCode.OK);

나는 이것이 오래된 질문이라는 것을 알고 있지만이 주제를 검색하는 동안 우연히 발견했고 테스트를 HttpClient쉽게 할 수있는 아주 좋은 해결책을 찾았습니다 .

너겟을 통해 사용할 수 있습니다.

https://github.com/richardszalay/mockhttp

PM> Install-Package RichardSzalay.MockHttp

다음은 사용법에 대한 간략한 설명입니다.

var mockHttp = new MockHttpMessageHandler();

// Setup a respond for the user api (including a wildcard in the URL)
mockHttp.When("http://localost/api/user/*")
        .Respond("application/json", "{'name' : 'Test McGee'}"); // Respond with JSON

// Inject the handler or client into your application code
var client = new HttpClient(mockHttp);

var response = await client.GetAsync("http://localost/api/user/1234");
// or without await: var response = client.GetAsync("http://localost/api/user/1234").Result;

var json = await response.Content.ReadAsStringAsync();

// No network connection required
Console.Write(json); // {'name' : 'Test McGee'}

github 프로젝트 페이지에 대한 자세한 정보. 이것이 유용 할 수 있기를 바랍니다.


await 연산자를 예상하는 비동기 메서드에 대한 경고를 피하기 위해 Task.FromResult사용하는 @Darrel Miller 의 대답 을 약간 변경합니다 .

public class FakeResponseHandler : DelegatingHandler
{
    private readonly Dictionary<Uri, HttpResponseMessage> _FakeResponses = new Dictionary<Uri, HttpResponseMessage>();

    public void AddFakeResponse(Uri uri, HttpResponseMessage responseMessage)
    {
        _FakeResponses.Add(uri, responseMessage);
    }

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
    {
        if (_FakeResponses.ContainsKey(request.RequestUri))
        {
            return Task.FromResult(_FakeResponses[request.RequestUri]);
        }
        else
        {
            return Task.FromResult(new HttpResponseMessage(HttpStatusCode.NotFound) { RequestMessage = request });
        }
    }
}

You might take a look at Microsoft Fakes, especially at the Shims-section. With them, you're able to modify the behaviours of your HttpClient itself. Prerequisite is, that you're using VS Premium or Ultimate.

ReferenceURL : https://stackoverflow.com/questions/22223223/how-to-pass-in-a-mocked-httpclient-in-a-net-test

반응형