使用HttpRequestMessage对

时间:2018-03-26 18:23:08

标签: unit-testing azure azure-functions asp.net-core-webapi

尝试在Visual Studio中单元测试HTTP触发器Azure函数时,我遇到了一些问题。我创建了一个GitHub repo(https://github.com/ericdboyd/TestingAzureFunctions),其中包含一个示例解决方案,其中包含Azure Function项目和演示问题的Unit Test项目。

首先,当我引入Microsoft.AspNet.WebApi.Core时,它会在尝试使用IContentNegotiator时在System.Web.Http和Microsoft.AspNetCore.Mvc.WebApiCompatShim之间产生冲突。唯一的方法是使用以下内容在测试项目的csproj文件中为WebApiCompatShim添加别名:

<Target Name="ChangeAliasesOfStrongNameAssemblies" BeforeTargets="FindReferenceAssembliesForReferences;ResolveReferences">
<ItemGroup>
  <ReferencePath Condition="'%(FileName)' == 'Microsoft.AspNetCore.Mvc.WebApiCompatShim'">
    <Aliases>webapicompatshim</Aliases>
  </ReferencePath>
</ItemGroup>

一旦我克服了这个错误,我就会遇到这个问题,而这个问题一直无法解决。使用HttpRequestMessage.CreateResponse扩展方法在Azure函数中返回响应,我得到“没有服务类型'System.Net.Http.Formatting.IContentNegotiator'已经注册。”当我尝试测试它。我已经尝试构建一个HttpRequestMessage,我认为应该使用下面的代码使用这个扩展方法,这个代码也可以在GitHub仓库中找到,但是它失败了,我已经努力尝试过几个小时了。< / p>

IServiceCollection services = new ServiceCollection();
services.AddOptions();
services.AddSingleton(typeof(IContentNegotiator), typeof(DefaultContentNegotiator));
IServiceProvider serviceProvider = services.BuildServiceProvider();

var httpContext = new DefaultHttpContext {RequestServices = serviceProvider};

var httpConfiguration = new HttpConfiguration();

HttpRequestMessage request = new HttpRequestMessage
{
    Method = HttpMethod.Post,
    RequestUri = new Uri(url),
    Content = new StringContent(content, Encoding.UTF8, "application/json"),
    Properties =
    {
        { HttpPropertyKeys.HttpConfigurationKey, httpConfiguration },
        { nameof(HttpContext), httpContext} 
    }
};

如果我不使用CreateResponse扩展方法,只需创建HttpResponseMessage对象,它就可以正常工作。

为了设置一些额外的上下文,我知道这不是对Azure功能执行的代码进行单元测试的最佳方法。我对这些代码进行了更细致的单元测试。但我希望能够对执行http请求和对该逻辑的响应之间的映射的Azure功能进行单元测试。

GitHub仓库中有两个Azure功能和两个单元测试,一个使用扩展方法设置,一个没有证明问题。但其他一切都是一样的。

2 个答案:

答案 0 :(得分:1)

不能直接解决您的问题,但它可以帮助您继续前进。

您正在使用Azure Functions v2 - .NET Standard版本。这个版本目前处于测试阶段,因此它有点阴暗:缺少文档并且存在一些问题。

在V2中,建议您使用HttpRequest课程和IActionResult代替经典&#39; HttpRequestMessageHttpResponseMessage。默认模板具有如下签名:

public static IActionResult Run(
    [HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequest req, TraceWriter log)

这应该可以让你摆脱你的垫片并对类似于ASP.NET Core方式的功能进行单元测试。

答案 1 :(得分:0)

在响应时指定jsonformatter,如下所示

  

req.CreateResponse(HttpStatusCode.OK,$“Hello,{name}”,new JsonMediaTypeFormatter())