首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >嘲弄HttpResponse WriteAsync

嘲弄HttpResponse WriteAsync
EN

Stack Overflow用户
提问于 2018-04-27 15:02:15
回答 2查看 4.7K关注 0票数 9

我试图在模拟的WriteAsync上调用一个模拟HttpResponse,但我找不出要使用的语法。

代码语言:javascript
复制
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 :扩展方法上的无效设置:X => x.WriteAsync(It.IsAny(),It.IsAny())

最终,我想验证正确的字符串已经写入响应。

如何正确设置这个?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-04-27 15:26:04

Moq不能Setup扩展方法。如果您知道扩展方法访问什么,那么有些情况下可以通过扩展方法模拟安全路径。

WriteAsync(HttpResponse,String,CancellationToken)

将给定的文本写入响应体。将使用UTF-8编码。

通过以下重载直接访问HttpResponse.Body.WriteAsync,其中BodyStream

代码语言:javascript
复制
/// <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);
}

这意味着您需要模拟response.Body.WriteAsync

代码语言:javascript
复制
//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);

回调用于捕获传递给模拟成员的参数。它的值存储在一个变量中,以便在稍后的测试中声明。

票数 8
EN

Stack Overflow用户

发布于 2020-03-10 23:43:06

为了完整起见,这里有一个在.NET Core3.1中工作的解决方案:

代码语言:javascript
复制
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);
}
票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50065209

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档