- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试模拟 HttpMessageHandler 以便使用 HttpClient 测试类。
模拟似乎有效并且结果不错,但是当验证方法 SendAsunc 被调用的次数时,它返回 0 而不是 1...
知道为什么吗?我是 Moq 的新手,不了解它的所有复杂之处。
测试方法
[TestMethod]
public void LoginTest_ShouldTrue()
{
// Setup the handler
var mockHandler = new Mock<HttpMessageHandler>(MockBehavior.Strict);
mockHandler.Protected()
// Setup the protected method to mock
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>()
)
// prepare the expected response of the mocked http call
.ReturnsAsync(new HttpResponseMessage()
{
StatusCode = System.Net.HttpStatusCode.OK,
Content = new StringContent("You are connected as xxxxxxxxxxxxxxxx.")
})
.Verifiable();
// Use HttpClient with mocked HttpMessageHandler
var httpClient = new HttpClient(mockHandler.Object);
var objectToTest = new LoginApi(new Uri("https://test.com/"), ref httpClient);
// Perform test
var user = "test_user";
var pass = "test_password_123";
objectToTest.LoginAsync(user, pass).Result.Should().Be(true);
objectToTest.IsLoggedIn.Should().Be(true);
// Check the http call was as expected
var expectedUri = new Uri("https://test.com/cgi/session.pl");
var formVariables = new List<KeyValuePair<string, string>>(3);
formVariables.Add(new KeyValuePair<string, string>(".submit", "Sign+in"));
formVariables.Add(new KeyValuePair<string, string>("user_id", user));
formVariables.Add(new KeyValuePair<string, string>("password", pass));
var expectedContent = new FormUrlEncodedContent(formVariables);
mockHandler.Protected().Verify<Task<HttpResponseMessage>>(
"SendAsync",
Times.Exactly(1), // We expected a single external request
ItExpr.Is<HttpRequestMessage>(req =>
req.Method == HttpMethod.Post // We expected a POST request
&& req.RequestUri == expectedUri // to this uri
&& req.Content == expectedContent // with this content
),
ItExpr.IsAny<CancellationToken>()
);
}
测试的方法
public class LoginApi : ILoginApi
{
private readonly Uri baseUri;
private readonly HttpClient client;
public bool IsLoggedIn { get; protected set; }
public LoginApi(Uri baseUri, ref HttpClient client)
{
this.baseUri = baseUri;
this.client = client;
IsLoggedIn = false;
}
public async Task<bool> LoginAsync(string user, string pass)
{
var formVariables = new List<KeyValuePair<string, string>>(3);
formVariables.Add(new KeyValuePair<string, string>(".submit", "Sign+in"));
formVariables.Add(new KeyValuePair<string, string>("user_id", user));
formVariables.Add(new KeyValuePair<string, string>("password", pass));
var targetUri = new Uri(baseUri, string.Join('/', URLs.ServiceCgiSuffix, "session.pl"));
var res = await client.PostAsync(targetUri, new FormUrlEncodedContent(formVariables));
var content = await res.Content.ReadAsStringAsync();
IsLoggedIn = content.Contains("You are connected as");
return IsLoggedIn;
}
public async Task<bool> LogoutAsync()
{
var formVariables = new List<KeyValuePair<string, string>>(1);
formVariables.Add(new KeyValuePair<string, string>(".submit", "Sign-out"));
var targetUri = new Uri(baseUri, string.Join('/', URLs.ServiceCgiSuffix, "session.pl"));
var res = await client.PostAsync(targetUri, new FormUrlEncodedContent(formVariables));
var content = await res.Content.ReadAsStringAsync();
IsLoggedIn = !content.Contains("See you soon!");
return !IsLoggedIn;
}
}
错误详情
StackTrace:
at Moq.Mock.VerifyCalls(Mock targetMock, InvocationShape expectation, LambdaExpression expression, Times times, String failMessage) in C:\projects\moq4\src\Moq\Mock.cs:line 414
at Moq.Mock.Verify[T,TResult](Mock`1 mock, Expression`1 expression, Times times, String failMessage) in C:\projects\moq4\src\Moq\Mock.cs:line 315
at Moq.Protected.ProtectedMock`1.Verify[TResult](String methodName, Times times, Object[] args) in C:\projects\moq4\src\Moq\Protected\ProtectedMock.cs:line 171
at OpenFoodFacts.Test.Login.LoginApiTest.LoginTest_ShouldTrue() in path\to\project\LoginApiTest.cs:line 56
Result message:
Test method OpenFoodFacts.Test.Login.LoginApiTest.LoginTest_ShouldTrue threw exception:
Moq.MockException:
Expected invocation on the mock exactly 1 times, but was 0 times:
mock => mock.SendAsync(
It.Is<HttpRequestMessage>(req => (req.Method == POST && req.RequestUri == https://test.com/cgi/session.pl) && req.Content == FormUrlEncodedContent),
It.IsAny<CancellationToken>())
Configured setups:
HttpMessageHandler mock => mock.SendAsync(It.IsAny<HttpRequestMessage>(), It.IsAny<CancellationToken>())
Performed invocations:
HttpMessageHandler.SendAsync(Method: POST, RequestUri: 'https://test.com/cgi/session.pl', Version: 2.0, Content: System.Net.Http.FormUrlEncodedContent, Headers:
{
Content-Type: application/x-www-form-urlencoded
}, CancellationToken)
最佳答案
问题在于请求内容是否相等,如果两个操作数引用同一个对象,则使用==运算符比较两个对象返回true;他们没有。如果你删除了这一行“&& req.Content == expectedContent
”你的测试会工作正常。除此之外,您的测试和模拟设置运行良好。
关于c# - 模拟 HttpMessageHandler 时未调用 SendAsync,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52705482/
我正在尝试模拟 HttpMessageHandler 以便使用 HttpClient 测试类。 模拟似乎有效并且结果不错,但是当验证方法 SendAsunc 被调用的次数时,它返回 0 而不是 1..
我需要根据使用应用程序的最终用户在应用程序运行时传递网络凭据以模拟域用户。我无法弄清楚如何通过与单个用户相关联的 Services.AddHttpClient 和 HttpClientFactory
DelegatingHandler继承自 HttpMessageHandler .但是,我不明白其中的区别,因为您必须实现相同的方法,SendAsync使两者都起作用。 这两个处理程序有什么区别?我应
如果我在 HttpMessageHandler 中有一个异步调用,它是否应该使用 .ConfigureAwait 方法,例如 /// /// Handler to assign the MD5 ha
我在类库中有一个自定义的 DelegatingHandler,我需要用 Autofac 注册它。 webapi 宿主解决了它对运行时的依赖,因此宿主没有对该库的引用。 public class Loc
HttpClient需要 HttpMessageHandler它的两个构造函数中的参数。 有没有什么简单的方法可以在创建 HttpClient 之后更改处理程序而不创建新的 HttpClient 实例
对于基本身份验证,我已经实现了自定义 HttpMessageHandler基于 Darin Dimitrov 的答案中显示的示例:https://stackoverflow.com/a/1153634
在 ASP.NET 4.5 MVC 4 Web API 项目中,我想添加自定义 HttpMessageHandler。我更改了 WebApiConfig 类(在\App_Satrt\WebApiCon
在决定我想为测试发回什么样的响应之前,有没有办法获取http请求的内容?多个测试将使用此类,每个测试将有多个 http 请求。此代码无法编译,因为 lambda 不是异步的,并且其中有一个等待。我是
我有一个单元测试,它通过传入 HttpRequestMessage 实例并接收返回的 HttpResponseMessages 实例来调用类库。在这方面,它与测试 WebApi ApiControll
我在 .NET Core 2.1 应用程序上有一份夜间工作,向 https://server/api/values 发出请求此请求应该从服务器到服务器本身完成(一种 TestServer 行为),没有
我有一个使用 HttpClient 的控制台应用程序发出网络请求。 var client = new HttpClient(); 我正在尝试添加多个 HttpMessageHandler到它( Del
作为我正在处理的 ASP.Net Core 项目的一部分,我需要从我的 WebApi 中与许多不同的基于 Rest 的 API 端点进行通信。为了实现这一点,我使用了许多服务类,每个服务类都实例化一个
看来这两者有着相似的目的。如果能看到一些示例,了解何时使用其中一种的优点和缺点,并指出主要区别是什么,那就太好了。 最佳答案 The major difference between their tw
尝试在 StructureMap ala 中定义一个 HttpClient 单例: For().Singleton().UseIfNone(); 这会导致运行时出现以下错误(依赖注入(inject)时
对于开发人员, 我会 mock HttpMessageHandler 来测试 HttpClient,我的问题是我将如何根据 URL 和 Http 方法?所以响应将是方法和 URL 的函数: Get +
我在工厂注册我的 HttpClient: services.AddHttpClient() .SetHandlerLifetime(TimeSpan.FromMinutes(2)); 这个 I
请任何人告诉我以下三个模块如何在 asp.net Web API 2.1 中协同工作 欧文中间件 HttpMessageHandler(或 DelegatingHandler) 异常处理程序 我正在尝
在不使用 ASP.NET Core 的 DI 的情况下,您可以使用其构造函数将包含 cookie 容器的 ClientHandler 放入 HttpClient 对象中,类似于以下内容:
我是一名优秀的程序员,十分优秀!