正确的方法来模拟HttpClient和发送/获取cookie

时间:2017-05-19 04:07:46

标签: c# unit-testing cookies moq dotnet-httpclient

我使用moq来模拟我为HttpClient类创建的包装器:

public interface IHttpClientWrapper
{
    Task<HttpResponseMessage> PostAsync(Uri uri,
                                        HttpContent content,
                                        CookieContainer cookies = null);
}

PostAsync的“正常”实施中,我只是将调用委托给HttpClient

public Task<HttpResponseMessage> PostAsync(Uri uri, HttpContent content, CookieContainer cookies = null)
{
    var client = cookies == null ? new HttpClient()
        : new HttpClient(new HttpClientHandler { CookieContainer = cookies });

    return client.PostAsync(uri, content);
}

所以,在我的应用程序中,一切正常,我得到服务器设置的cookie(cookies.Count不是0

对于我的测试,我有Mock<IHttpClientWrapper>,并且我已设置其PostAsync方法以返回new HttpResponseMessage。我还调用HttpResponseMessage.Headers.AddCookies方法为此响应添加2个cookie。

但是当我以这样的方式调用我的模拟对象时:

/* I setup url and content */
var mock = new Mock<IHttpClientHelper>();
mock.Setup(/* setup PostAsync to return the response I create */)...
var cookies = new CookieContainer();
var response = await mock.PostAsync(url, content, cookies);

然后,cookies.Count始终为0

所以,我想知道与调用实际服务器有什么不同?我需要额外的标题吗?我如何在这里设置cookie?

1 个答案:

答案 0 :(得分:1)

CookieContainer作为参数传递给PostAsync方法。 PostAsyncCookiesContainer添加Cookie的事实是此方法的副作用特定 IHttpClientHelper实施的详细信息。 new Mock<IHttpClientHelper>创建另一个实施,但不添加Cookie。

因此,如果你想模拟将cookies添加到容器中,则需要额外的设置

mock.Setup(_ => _.PostAsync(It.IsAny<Uri>(), It.IsAny<HttpContent>(), It.IsAny<CookieContainer>()))
    .Callback<Uri, HttpContent, CookieContainer>((u, c, cookieContainer) => 
    {
        // Add required cookies here
        cookieContainer.Add(...);
    });

CallbackMock设置副作用的方法。