UnitTest HttpResponse WriteAsync 和 CopyToAsync
UnitTest HttpResponse WriteAsync and CopyToAsync
我想对下一个方法进行单元测试:
public static async Task SetResponseBody(HttpResponse response, string message)
{
var originalResponseBody = response.Body;
var responseBody = new MemoryStream();
response.Body = responseBody;
response.ContentType = "application/json";
dynamic body = new { Message = message };
string json = JsonSerializer.Serialize(body);
await response.WriteAsync(json);
response.Body.Seek(0, SeekOrigin.Begin);
await responseBody.CopyToAsync(originalResponseBody);
}
最后两行来自。
当前的单元测试实现是:
[TestMethod]
public async Task SetResponseBody_TestMessageAsync()
{
var expected = "TestMessage";
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);
})
.Returns(Task.CompletedTask);
await ResponseRewriter.SetResponseBody(responseMock.Object, expected);
}
单元测试由于 NullReferenceException 而失败,一旦测试命中“await response.WriteAsync(json);
”代码行就会引发该异常。你能指出正确的方向来修复这个异常,这样测试就会通过吗?
总结:单元测试需要检查给定的 'TestMessage' 是否实际写入了响应的正文。
背景资料:
我正在调用 SetResponseBody
方法,以便在 AddOpenIdConnect
.
引发“OnRedirectToIdentityProvider
”事件后立即修改响应主体
OnRedirectToIdentityProvider = async e =>
{
// e is of type RedirectContext
if (e.Request.Path.StartsWithSegments("/api")))
{
if (e.Response.StatusCode == (int)HttpStatusCode.OK)
{
e.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
// TestMessage is a const
// e.Response is readonly (get) so it's not possible to set it directly.
await ResponseRewriter.SetResponseBody(e.Response, TestMessage);
}
e.HandleResponse();
}
await Task.CompletedTask;
}
.NET Core 3.1, WebApi, OpenId
抽象 HttpResponse
需要配置太多内部结构才能在模拟时按预期工作。
我建议使用 DefaultHttpContext
并提取在该上下文中创建的默认响应。
[TestMethod]
public async Task SetResponseBody_TestMessageAsync() {
//Arrange
string expected = "TestMessage";
string actual = null;
HttpContext httpContext = new DefaultHttpContext();
HttpResponse response = httpContext.Response
//Act
await ResponseRewriter.SetResponseBody(response, expected);
//Assert
//...
}
对于断言,提取响应主体的内容并断言其预期行为。
我们不能为所有方法,尤其是系统库编写单元测试。
所以解决方案是制作虚函数并使用下面的方法而不是直接等待 response.WriteAsync(json);
public virtual async Task WriteAsync(string json)
{
await response.WriteAsync(json);
}
然后
yourClassObject_Where_SetResponseBody_Exist.Setup(m => m.WriteAsync
(It.IsAny<string>()));
我想对下一个方法进行单元测试:
public static async Task SetResponseBody(HttpResponse response, string message)
{
var originalResponseBody = response.Body;
var responseBody = new MemoryStream();
response.Body = responseBody;
response.ContentType = "application/json";
dynamic body = new { Message = message };
string json = JsonSerializer.Serialize(body);
await response.WriteAsync(json);
response.Body.Seek(0, SeekOrigin.Begin);
await responseBody.CopyToAsync(originalResponseBody);
}
最后两行来自
当前的单元测试实现是:
[TestMethod]
public async Task SetResponseBody_TestMessageAsync()
{
var expected = "TestMessage";
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);
})
.Returns(Task.CompletedTask);
await ResponseRewriter.SetResponseBody(responseMock.Object, expected);
}
单元测试由于 NullReferenceException 而失败,一旦测试命中“await response.WriteAsync(json);
”代码行就会引发该异常。你能指出正确的方向来修复这个异常,这样测试就会通过吗?
总结:单元测试需要检查给定的 'TestMessage' 是否实际写入了响应的正文。
背景资料:
我正在调用 SetResponseBody
方法,以便在 AddOpenIdConnect
.
OnRedirectToIdentityProvider
”事件后立即修改响应主体
OnRedirectToIdentityProvider = async e =>
{
// e is of type RedirectContext
if (e.Request.Path.StartsWithSegments("/api")))
{
if (e.Response.StatusCode == (int)HttpStatusCode.OK)
{
e.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
// TestMessage is a const
// e.Response is readonly (get) so it's not possible to set it directly.
await ResponseRewriter.SetResponseBody(e.Response, TestMessage);
}
e.HandleResponse();
}
await Task.CompletedTask;
}
.NET Core 3.1, WebApi, OpenId
抽象 HttpResponse
需要配置太多内部结构才能在模拟时按预期工作。
我建议使用 DefaultHttpContext
并提取在该上下文中创建的默认响应。
[TestMethod]
public async Task SetResponseBody_TestMessageAsync() {
//Arrange
string expected = "TestMessage";
string actual = null;
HttpContext httpContext = new DefaultHttpContext();
HttpResponse response = httpContext.Response
//Act
await ResponseRewriter.SetResponseBody(response, expected);
//Assert
//...
}
对于断言,提取响应主体的内容并断言其预期行为。
我们不能为所有方法,尤其是系统库编写单元测试。 所以解决方案是制作虚函数并使用下面的方法而不是直接等待 response.WriteAsync(json);
public virtual async Task WriteAsync(string json)
{
await response.WriteAsync(json);
}
然后
yourClassObject_Where_SetResponseBody_Exist.Setup(m => m.WriteAsync
(It.IsAny<string>()));