在单元测试中模拟 HTTP 请求

本文关键字:HTTP 请求 模拟 单元测试 | 更新日期: 2023-09-27 18:36:49

我开始学习最小起订量,但我有这个问题。我需要模拟类/接口,它发出HTTP GET和HTTP POST请求并返回HTML字符串作为服务器响应。

我简化了我的代码。这是:

public interface IHttpManager
{
    /// <summary>
    /// Make HTTP GET request on server and return HTML string
    /// </summary>
    string HttpGet(Uri url, CookieContainer cookies, HttpRequestSettings settings);
    /// <summary>
    /// Make HTTP POST request and return HTML string
    /// </summary>
    string HttpPost(Uri url, string postData, CookieContainer cookies, HttpRequestSettings settings);
}

我在类ConnectionManager中使用IHttpManager,可以在服务器上登录或注销。

public interface IConectionManager
{
    /// <summary>
    /// Connect to server and parse HTML response
    /// </summary>
    Result<T> LogIn(string nick, string password);
    /// <summary>
    /// Log off and parse HTML response
    /// </summary>
    /// <param name="account"></param>
    void LogOff(Acccount account);
}
public class ConnectionManager : IConectionManager
{
    private IHttpManager _httpManager;
    private HttpRequestSettings _httpRequestSettings;
    public ConnectionManager(IHttpManager httpManager, HttpRequestSettings httpRequestSettings)
    {
        _httpManager = httpManager;
        _httpRequestSettings = httpRequestSettings;
    }
    public Result<Account> LogIn(string nick, string password)
    {
        // I simplified this method
        // How correct mock IHttpManager, because it must return HTML string
        // so in Moq in Setup return hard coded HTML string which represent server response ?
        string htmlStringResponse = _httpManager.HttpGet(ServerUrl.LogOn, new CookieContainer(), _httpRequestSettings);
        // parse HTML string and return result
    }
    // ...
}

I方法LogIn的单元测试。我想嘲笑IHttpManager.但我不知道如何以正确的方式做。

我试试这个:

// Arrange
var mockHttpManager = new Mock<IHttpManager>();
mockHttpManager.Setup(x=>x.HttpGet()).Returns(()=>"HTML SERVER RESPONSE");
var sut = new ConnectionManager(mockHttpManager.Object, new HttpRequestSettings());
// act
sut.Login("nick", "123")
// Assert

在单元测试中模拟 HTTP 请求

似乎您需要在模拟上设置参数期望:

mockHttpManager
    .Setup(x => x.HttpGet(
        It.IsAny<Uri>(),
        It.IsAny<CookieContainer>(),
        It.IsAny<HttpRequestSettings>()))
    .Returns(() => "HTML SERVER RESPONSE");

理想情况下,应使用 It.Is<T>() 来匹配参数,以确保使用预期的确切参数调用该方法。例如,您可能想要测试您的Login方法是否使用 ServerUrl.LogOn 调用HttpGet

It.Is<Uri>(uri => uri == ServerUrl.LogOn),