【问题标题】:How can I mock HttpRequestMessage, specifically the CreateResponse?如何模拟 HttpRequestMessage,特别是 CreateResponse?
【发布时间】:2017-12-27 14:41:50
【问题描述】:

如何模拟HttpRequestMessage,特别是CreateResponse

var requestMessage = Substitute.For<HttpRequestMessage>();
requestMessage.CreateResponse().ReturnsForAnyArgs(
       new HttpResponseMessage(HttpStatusCode.OK));

但我得到了例外......

NSubstitute.Exceptions.CouldNotSetReturnDueToNoLastCallException: 
  'Could not find a call to return from.

我已经看到问题了...How to mock the CreateResponse<T> extension method on HttpRequestMessage

并关联...ASP.NET WebApi unit testing with Request.CreateResponse...

但他们似乎并没有真正最终嘲笑 CreateResponse

其他 cmets:

我正在尝试围绕 Azure 预编译 C# 函数的启动器编写单元测试...

[FunctionName("Version")]
public static HttpResponseMessage Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]
    HttpRequestMessage req,
    TraceWriter log)
{
    log.Info("Version function processed a request ... ");

    return req.CreateResponse(HttpStatusCode.OK, "Version 0.0.1");
}

和实际测试,我想模拟 HttpRequestMessage,特别是我得到错误的 CreateReponse 是......

[TestMethod]
public void Version_returns_value()
{
    var requestMessage = Substitute.For<HttpRequestMessage>();
    requestMessage.CreateResponse(Arg.Any<HttpStatusCode>(), Arg.Any<string>())
                  .Returns(new HttpResponseMessage(HttpStatusCode.OK));
    var log = new CustomTraceWriter(TraceLevel.Verbose);

    var httpResponseMessage = VersionFunction.Run(requestMessage, log);
    var httpContent = httpResponseMessage.Content;

    httpContent.Should().Be("Version 0.0.1 :: valid");
}

【问题讨论】:

  • NSubstitute(和其他基于 DynamicProxy 的库)不能模拟扩展方法。 HttpRequestMessage 没有 virtual 成员,因此大多数模拟库也无济于事。您能否提供有关您要测试的内容的更多信息?如果模拟在这里不能直接使用,那么我们可以讨论其他可能有帮助的选项。 :)
  • @DavidTchepak 我已经在我的问题中添加了更多信息,关于我正在尝试做什么......

标签: c# unit-testing asp.net-web-api mocking nsubstitute


【解决方案1】:

这里不需要嘲笑任何东西。对于此测试,所有内容都可以安全地存根。 CreateResponse 是一种扩展方法,它在内部使用请求的关联HttpConfiguration。这是在测试中使用它之前需要设置的唯一要求。

这样,如果您按如下方式更新您的测试,您应该能够正确地执行您的测试。

[TestMethod]
public async Task Version_returns_value() {
    var expected = "\"Version 0.0.1\"";
    var config = new HttpConfiguration();
    var requestMessage = new HttpRequestMessage();
    requestMessage.SetConfiguration(config);

    var log = new CustomTraceWriter(TraceLevel.Verbose);

    var httpResponseMessage = VersionFunction.Run(requestMessage, null);
    var httpContent = httpResponseMessage.Content;
    var content = await httpContent.ReadAsStringAsync();

    content.Should().Be(expected);
}

【讨论】:

  • @Nkosi 恐怕不高兴......测试方法 ChromebookFilterFunction.Tests.FunctionTests.Version_returns_value 抛出异常:System.MethodAccessException:尝试通过方法 'System.Web.Http.HttpConfiguration..ctor( System.Web.Http.HttpRouteCollection)' 访问方法 'System.Web.Http.HttpConfiguration.DefaultFormatters()' 失败。在 System.Web.Http.HttpConfiguration..ctor(HttpRouteCollection 路由) 在 System.Web.Http.HttpConfiguration..ctor()
  • @SteveC 我重新创建了您的测试减去 Trace 并且能够运行测试完成,没有例外,因为我对预期结果犯了一个小错误。您的 OP 中的代码是所有代码还是排除了可能导致此错误的代码。
  • @Nkosi 首先非常感谢您的回复,非常感谢您的帮助...我已经注释掉了文件中的其余代码,并在您的测试中复制并粘贴...仍然得到相同的 MethodAccessException。我正在使用 VS 2017 的预览版 4,因为我正在处理预编译的 Azure Functions,并且有很多预览版本的一些位,但不是 System.Net.Http。也就是说,我已经在我的测试项目中添加了很多 NuGet 包以试图让测试正常工作,所以也许我把它搞砸了???
  • 回到干净的解决方案。问题似乎是使用 System.Web.Http 命名空间中的 HttpConfiguration 。测试在本地编译,但是当我尝试在 VSTS 中构建时,出现构建错误...错误 CS0234:名称空间“System.Web”中不存在类型或名称空间名称“Http”(您是否缺少程序集参考?)。
  • 您可能需要检查您的 NuGet 包。它可能没有引用正确的库
猜你喜欢
  • 2012-06-18
  • 2016-01-04
  • 2019-06-16
  • 2019-08-23
  • 1970-01-01
  • 2020-12-06
  • 2011-08-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多