c# - 在单元测试中模拟 HTTP 请求

标签 c# testing mocking moq xunit.net

我开始学习起订量,但遇到了这个问题。我需要模拟类/接口(interface),它发出 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
    }

    // ...
}

我对方法 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

最佳答案

看来您需要在模拟上设置参数期望值:

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

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

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

关于c# - 在单元测试中模拟 HTTP 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19571251/

相关文章:

ruby-on-rails - Rspec 方法创建错误

mocking - 在breezejs上实现模拟数据服务(查询失败)

c# - 在 C# 中使用 Tcpclient 类发送和接收自定义对象

c# - System.Web.Routing.RouteCollection 和 System.Web.Mvc.RouteCollectionExtensions 都具有相同的简单名称 'IgnoreRouteInternal'

c# - 当我得到的只是消息时,如何判断我是否有 BufferedMessage 或 BodyWriterMessage?

unit-testing - 对微服务的每个版本进行一组测试?

c# - 为什么 Assembly.Load 在解析引用时似乎不影响当前线程(不是通过反射)?

python - `assert 1,2 == (2,3)` 不会在 python3 中引发 AssertionError

python - 仅模拟对象上的单个方法

c# - 我可以在 Rhino-Mocks 3.6 中使用 AAA 语法测试方法调用顺序吗?