如何在一种方法中模拟多个httpclient调用?

时间:2019-03-21 13:37:18

标签: unit-testing asp.net-core httpclient moq dotnet-httpclient

我有一个发送并行http请求的方法,如下所示:

    public async Task<string> GetEmails(string userName)
    {
        var source1Response = GetFromSource1(userName);
        var source2Response = GetFromSource2t(userName);

        await Task.WhenAll(source1Response, source2Response);
        var data1 = await source1Response;
        var data2 = await source2Response;
        return data1 + "," + data2;           
    }

    private async Task<string> GetFromSource1(string userName)
    {
        var url = "url to source 1";
        return await SendRequest(url, new { username = userName });
    }

    private async Task<string> GetFromSource2(string userName)
    {
        var url = "url to source 2";
        return await SendRequest(url, new { username = userName });
    }

    private async Task<string> SendRequest(string url, object json)
    {
        var uri = new Uri(string.Format(baseUrl)) + url;
        var request = new HttpRequestMessage(HttpMethod.Post, uri);
        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        request.Headers.Add("Authorization, "token");
        string jsonString = JsonConvert.SerializeObject(json);
        request.Content = new StringContent(jsonString, Encoding.UTF8, "application/json");
        var response = await _httpClient.SendAsync(request);
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadAsAsync<string>();
    }

现在,我想为GetEmails()方法编写单元测试,但问题是在1次调用的情况下我得到了模拟响应,但在第二次调用中却得到了null。这是httpClient的模拟:

        var expectedResponse = JsonConvert.SerializeObject("dummy1@example.com");
        var mockResponse =
            new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(expectedResponse) };
        mockResponse.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

        var mockHandler = new Mock<DelegatingHandler>();
        mockHandler
            .Protected()
            .Setup<Task<HttpResponseMessage>>(
                "SendAsync",
                ItExpr.Is<HttpRequestMessage>(
                    message => message.Headers.Contains("Authorization")
                               && message.Headers.Authorization.Scheme.Equals("Bearer")
                               && message.RequestUri.AbsoluteUri.Contains(string.Format("https://dummyUrl.com"))
                ),
                ItExpr.IsAny<CancellationToken>())
            .Returns(Task.FromResult(mockResponse));

        var httpClient = new HttpClient(mockHandler.Object);

现在,在使用GetFromSource1()方法的情况下,我得到的是“ dummy1@example.com”,但是在使用GetFromSource2的情况下,我得到的是空值。因此,如何为GetFromSource2创建模拟。我可以在DelegatingHandler的returns()方法中添加一些检查吗?

0 个答案:

没有答案