模拟 HttpResponse WriteAsync
Mocking HttpResponse WriteAsync
我正在尝试在模拟HttpResponse
上调用对 WriteAsync
的模拟,但我不知道要使用的语法。
var responseMock = new Mock<HttpResponse>();
responseMock.Setup(x => x.WriteAsync(It.IsAny<string>(), It.IsAny<CancellationToken>()));
ctx.Setup(x => x.Response).Returns(responseMock.Object);
测试炸弹出现以下错误:
System.NotSupportedException : Invalid setup on an extension method: x
=> x.WriteAsync(It.IsAny(), It.IsAny())
最终我想验证是否已将正确的字符串写入响应。
如何正确设置?
Moq 不能 Setup
扩展方法。如果您知道扩展方法访问什么,那么在某些情况下您可以通过扩展方法模拟安全路径。
WriteAsync(HttpResponse, String, CancellationToken)
Writes the given text to the response body. UTF-8 encoding will be used.
通过以下重载
直接访问 HttpResponse.Body.WriteAsync
,其中 Body
是 Stream
/// <summary>
/// Writes the given text to the response body using the given encoding.
/// </summary>
/// <param name="response">The <see cref="HttpResponse"/>.</param>
/// <param name="text">The text to write to the response.</param>
/// <param name="encoding">The encoding to use.</param>
/// <param name="cancellationToken">Notifies when request operations should be cancelled.</param>
/// <returns>A task that represents the completion of the write operation.</returns>
public static Task WriteAsync(this HttpResponse response, string text, Encoding encoding, CancellationToken cancellationToken = default(CancellationToken))
{
if (response == null)
{
throw new ArgumentNullException(nameof(response));
}
if (text == null)
{
throw new ArgumentNullException(nameof(text));
}
if (encoding == null)
{
throw new ArgumentNullException(nameof(encoding));
}
byte[] data = encoding.GetBytes(text);
return response.Body.WriteAsync(data, 0, data.Length, cancellationToken);
}
这意味着您需要 mock response.Body.WriteAsync
//Arrange
var expected = "Hello World";
string actual = null;
var responseMock = new Mock<HttpResponse>();
responseMock
.Setup(_ => _.Body.WriteAsync(It.IsAny<byte[]>(),It.IsAny<int>(), It.IsAny<int>(), It.IsAny<CancellationToken>()))
.Callback((byte[] data, int offset, int length, CancellationToken token)=> {
if(length > 0)
actual = Encoding.UTF8.GetString(data);
})
.ReturnsAsync();
//...code removed for brevity
//...
Assert.AreEqual(expected, actual);
回调用于捕获传递给模拟成员的参数。它的值存储在一个变量中,稍后将在测试中断言。
为了完整性,这里有一个似乎适用于 .NET Core 3.1 的解决方案:
const string expectedResponseText = "I see your schwartz is as big as mine!";
DefaultHttpContext httpContext = new DefaultHttpContext();
httpContext.Response.Body = new MemoryStream();
// Whatever your test needs to do
httpContext.Response.Body.Position = 0;
using (StreamReader streamReader = new StreamReader(httpContext.Response.Body))
{
string actualResponseText = await streamReader.ReadToEndAsync();
Assert.Equal(expectedResponseText, actualResponseText);
}
我正在尝试在模拟HttpResponse
上调用对 WriteAsync
的模拟,但我不知道要使用的语法。
var responseMock = new Mock<HttpResponse>();
responseMock.Setup(x => x.WriteAsync(It.IsAny<string>(), It.IsAny<CancellationToken>()));
ctx.Setup(x => x.Response).Returns(responseMock.Object);
测试炸弹出现以下错误:
System.NotSupportedException : Invalid setup on an extension method: x => x.WriteAsync(It.IsAny(), It.IsAny())
最终我想验证是否已将正确的字符串写入响应。
如何正确设置?
Moq 不能 Setup
扩展方法。如果您知道扩展方法访问什么,那么在某些情况下您可以通过扩展方法模拟安全路径。
WriteAsync(HttpResponse, String, CancellationToken)
Writes the given text to the response body. UTF-8 encoding will be used.
通过以下重载
直接访问HttpResponse.Body.WriteAsync
,其中 Body
是 Stream
/// <summary>
/// Writes the given text to the response body using the given encoding.
/// </summary>
/// <param name="response">The <see cref="HttpResponse"/>.</param>
/// <param name="text">The text to write to the response.</param>
/// <param name="encoding">The encoding to use.</param>
/// <param name="cancellationToken">Notifies when request operations should be cancelled.</param>
/// <returns>A task that represents the completion of the write operation.</returns>
public static Task WriteAsync(this HttpResponse response, string text, Encoding encoding, CancellationToken cancellationToken = default(CancellationToken))
{
if (response == null)
{
throw new ArgumentNullException(nameof(response));
}
if (text == null)
{
throw new ArgumentNullException(nameof(text));
}
if (encoding == null)
{
throw new ArgumentNullException(nameof(encoding));
}
byte[] data = encoding.GetBytes(text);
return response.Body.WriteAsync(data, 0, data.Length, cancellationToken);
}
这意味着您需要 mock response.Body.WriteAsync
//Arrange
var expected = "Hello World";
string actual = null;
var responseMock = new Mock<HttpResponse>();
responseMock
.Setup(_ => _.Body.WriteAsync(It.IsAny<byte[]>(),It.IsAny<int>(), It.IsAny<int>(), It.IsAny<CancellationToken>()))
.Callback((byte[] data, int offset, int length, CancellationToken token)=> {
if(length > 0)
actual = Encoding.UTF8.GetString(data);
})
.ReturnsAsync();
//...code removed for brevity
//...
Assert.AreEqual(expected, actual);
回调用于捕获传递给模拟成员的参数。它的值存储在一个变量中,稍后将在测试中断言。
为了完整性,这里有一个似乎适用于 .NET Core 3.1 的解决方案:
const string expectedResponseText = "I see your schwartz is as big as mine!";
DefaultHttpContext httpContext = new DefaultHttpContext();
httpContext.Response.Body = new MemoryStream();
// Whatever your test needs to do
httpContext.Response.Body.Position = 0;
using (StreamReader streamReader = new StreamReader(httpContext.Response.Body))
{
string actualResponseText = await streamReader.ReadToEndAsync();
Assert.Equal(expectedResponseText, actualResponseText);
}