UnitTest HttpResponse WriteAsync和CopyToAsync [英] UnitTest HttpResponse WriteAsync and CopyToAsync

查看:133
本文介绍了UnitTest HttpResponse WriteAsync和CopyToAsync的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想对下一种方法进行单元测试:

I would like to unit test the next method:

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);         
}

最后两行来自此帖子.

当前的单元测试实现是:

The current unit test implementation is:

[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); "代码行,就会引发NullReferenceException.您能为我指出正确的方向来解决此异常,以便测试通过吗?

The unit tests fails due to a NullReferenceException which is raised once the test hits the 'await response.WriteAsync(json);' line of code. Could you point me in the right direction in order to fix this exception, so the test will pass?

总结:单元测试需要检查给定的"TestMessage"是否实际写入响应的主体中.

Summarized: The unit tests needs to check if the given 'TestMessage' is actually written to the Body of the response.

背景信息:我正在调用 SetResponseBody 方法,以便在从 AddOpenIdConnect 引发" OnRedirectToIdentityProvider "事件后立即修改响应正文.

Background information: I'm calling the SetResponseBody method in order to modify the response body as soon as the 'OnRedirectToIdentityProvider' event is raised from AddOpenIdConnect.

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

.NET Core 3.1, WebApi, OpenId

推荐答案

对于抽象的 HttpResponse ,需要对其进行过多的内部配置,以使其在模拟时能够按预期工作.

There are too many internals that need to be configured for the abstract HttpResponse to work as intended when mocking it.

我建议使用 DefaultHttpContext 并提取在该上下文中创建的默认响应.

I would suggest using DefaultHttpContext and extracting the default response created within that context.

[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
    //...
}

对于断言,提取响应主体的内容并断言其预期的行为.

for the assertion, extract the content of the response body and assert its expected behavior.

这篇关于UnitTest HttpResponse WriteAsync和CopyToAsync的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆