【问题标题】:Unittest project Azure Functions could not load file or assembly 'Newtonsoft.Json'Unittest 项目 Azure Functions 无法加载文件或程序集“Newtonsoft.Json”
【发布时间】:2017-11-14 14:37:08
【问题描述】:

我为 here 提到的函数应用创建了一个测试项目。我写的 Http 触发的 Azure 函数,使用依赖注入(AzureFunctions.AutoFac),看起来像这样:

[DependencyInjectionConfig(typeof(DependencyConfig))]
public static class CreateDeclarationsFunction
{
    [FunctionName("CreateDeclarationsFunction")]
    public static HttpResponseMessage Run(
        [HttpTrigger(AuthorizationLevel.Function, "post", Route = "CreateDeclarations")]HttpRequestMessage req,
        TraceWriter log,
        [Inject]IDeclarationDataService declarationDataService,
        [Inject]IClientDataService clientDataService)
    {
        log.Info("Http triggered function: CreateDeclarationsFunction  processed a request.");

        try
        {
            var clients = clientDataService.GetAll().ToList();

            foreach (var client in clients)
            {
                // Create and save new declaration for each client
                declarationDataService.CreateAndSaveNew(client.Id);
            }
        }
        catch (Exception ex)
        {
            return req.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
        }

        return req.CreateResponse(HttpStatusCode.OK);
    }
}

还有 unittest 类(带有 Moq、Shouldly 和 NBuilder):

[TestClass]
public class CreateDeclarationsFunctionTest
{
    private Mock<IDeclarationDataService> _declarationDataService;
    private Mock<IClientDataService> _clientDataService;

    [TestInitialize]
    public void Initialize()
    {
        _declarationDataService = new Mock<IDeclarationDataService>();
        _clientDataService = new Mock<IClientDataService>();
    }

    [TestMethod]
    public void CreateDeclarations_ReturnsOk()
    {
        // Arrange
        var clients = Builder<Client>.CreateListOfSize(10).Build();

        _declarationDataService.Setup(x => x.CreateAndSaveNew(It.IsAny<int>()))
            .Returns(Builder<Declaration>.CreateNew().Build);

        // Act > Exception by calling the Run method
        var result = CreateDeclarationsFunction.Run(CreateRequest(""), new TraceWriterStub(TraceLevel.Info),
            _declarationDataService.Object, _clientDataService.Object);

        // Assert
        // TODO
    }

    private static HttpRequestMessage CreateRequest(string json)
    {
        // Just a mocked request
        var request = new HttpRequestMessage
        {
            Method = HttpMethod.Post,
            RequestUri = new Uri("https://localhost"),
            Content = new StringContent(json, Encoding.UTF8, "application/json")
        };

        return request;
    }
}

当我运行这个单元测试时,它给出了一个异常。

Result StackTrace:  
at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter..ctor()
   at System.Net.Http.Formatting.JsonMediaTypeFormatter..ctor()
   at System.Net.Http.Formatting.MediaTypeFormatterCollection.CreateDefaultFormatters()
   at System.Web.Http.HttpConfiguration.DefaultFormatters(HttpConfiguration config)
   at System.Web.Http.HttpConfiguration..ctor(HttpRouteCollection routes)
   at System.Net.Http.HttpRequestMessageExtensions.CreateErrorResponse(HttpRequestMessage request, HttpStatusCode statusCode, Func`2 errorCreator)
   at System.Net.Http.HttpRequestMessageExtensions.CreateErrorResponse(HttpRequestMessage request, HttpStatusCode statusCode, Exception exception)
   at FunctionApp.CreateDeclarationsFunction.Run(HttpRequestMessage req, TraceWriter log, IDeclarationDataService declarationDataService, IClientDataService clientDataService)
   at FunctionApp.Tests.CreateDeclarationsFunctionTest.CreateDeclarations_ReturnsOk() in C:\TFS\...\FunctionApp.Tests\CreateDeclarationsFunctionTest.cs:line 63
Result Message: 
Test method FunctionApp.Tests.CreateDeclarationsFunctionTest.CreateDeclarations_ReturnsOk threw exception: 
System.IO.FileLoadException: Could not load file or assembly 'Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

FunctionApp 有 2 个对 Newtonsoft.Json (9.0.1) 的嵌套引用,但没有对版本 6.0.0.0 的引用。

Dependencies > Nuget > Microsoft.NET``.Sdk.Functions (1.0.6) > Newtonsoft.Json (9.0.1)

Dependencies > Nuget > AzureFunctions.Autofac (2.0.0) > Microsoft.Azure.Webjobs (2.1.0-beta4) > Newtonsoft.Json (9.0.1)

测试项目引用了FunctionApp 项目。该异常仅在单元测试时显示,而不是在其运行(并从浏览器调用)时显示。 有人有上限异常的解决方案吗?谢谢。

更新

我发现返回req.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);时会出现System.IO.FileLoadException

当返回 req.CreateResponse(HttpStatusCode.OK); 时,它不会给出提到的异常。

【问题讨论】:

  • 您的测试项目中是否有一个带有 Newtonsoft.Json 绑定重定向的 app.config 文件?在那里进行适当的绑定重定向(类似于:github.com/Azure/azure-webjobs-sdk-script/blob/…)可能会有所帮助
  • @FabioCavalcante,这确实是答案。谢谢!

标签: c# .net unit-testing azure azure-functions


【解决方案1】:

我认为由于我设置测试项目的方式(最初.NET standard,然后手动将目标框架转换为.NET Framework 4.6.1,如here所述),测试项目中没有生成app.config文件。此外,我认为当在解决方案中部分更新 nuget 包的版本时,这样的测试项目设置不会自动为 nuget 包生成绑定重定向。

正如@FabioCavalcante 提到的,我必须手动将app.config 文件添加到测试项目并为Newtonsoft.Json 放置绑定重定向。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

【讨论】:

    猜你喜欢
    • 2020-11-01
    • 2017-07-25
    • 2016-12-16
    • 1970-01-01
    • 2014-04-08
    • 1970-01-01
    • 1970-01-01
    • 2017-12-31
    • 1970-01-01
    相关资源
    最近更新 更多