微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

UnitTest HttpResponse WriteAsync 和 CopyToAsync

如何解决UnitTest HttpResponse WriteAsync 和 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);         
}

最后两行来自this post

当前的单元测试实现是:

[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<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);”行代码,就会引发该异常。您能否指出正确的方向以修复此异常,以便测试通过?

总结:单元测试需要检查给定的“Te​​stMessage”是否实际写入响应的正文。

背景信息: 我正在调用 SetResponseBody 方法,以便在从 OnRedirectToIdentityProvider 引发“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

解决方法

有太多的内部结构需要配置,以便抽象 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>()));

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?