首页 > 解决方案 > SpecflowPlusRunner 使用旧版本的 Newtonsoft,Json 的奇怪行为 - 你如何更新它?

问题描述

我有一个 dotnet core 3.1 类库,提供一些服务实现。我想使用 Specflow 创建一些 BDD 测试来测试我的服务的各种场景。

我创建了一个使用 SpecflowPlus 测试运行器的 Specflow 测试项目。如果我检查我的 bin 文件夹中的“deps.json”文件,所有对 NewtonSoft.Json 的引用都设置为版本 12.0.3 - 当前是最新版本。

但是,当构建解决方案时,一些文件被复制到这个位置\Specflow.Tests\bin\Debug\netcoreapp3.1\SpecFlowPlusRunner\——其中一个是\Specflow.Tests\bin\Debug\netcoreapp3.1\SpecFlowPlusRunner\netcoreapp3.1\Newtonsoft.Json.dll

这个版本的 Newtonsoft.Json 只有 11.0.2

SpecflowPlusRunner 的 Newtonsoft.Json.dll 副本的文件属性

如果我查看“Manage Nuget Packages for Solution”并切换到 Consolidation 选项卡,则引用的所有版本都是 12.0.3 - 我手动将 Newtonsoft.Json 添加到所有项目中,以尝试使版本相等。

当我运行测试时,我得到这个错误:

System.InvalidCastException: '[A]Newtonsoft.Json.Linq.JObject cannot be cast to [B]Newtonsoft.Json.Linq.JObject. 
Type A originates from 'Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' in the context 'Default' at location 'C:\Source\Repos\BSP_Infrastructure\deployment\CleanUp\src\WTW.ICT.BSP.CleanUp.Specflow.Tests\bin\Debug\netcoreapp3.1\SpecFlowPlusRunner\netcoreapp3.1\Newtonsoft.Json.dll'. 
Type B originates from 'Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' in the context 'Default' at location 'C:\Users\ian64639\.nuget\packages\newtonsoft.json\12.0.3\lib\netstandard2.0\Newtonsoft.Json.dll'.'

我的代码在类库内部进行了一些转换:

public async Task<string[]> GetSpaUris(string id)
{
   var app = await GetApplicationRegistrationAsync(id).ConfigureAwait(false);
   return GetSpaUris(app);
}

public string[] GetSpaUris(Application application) => ((JArray)((JObject)application.AdditionalData["spa"])["redirectUris"]).ToObject<string[]>();

并返回一个字符串数组。我不返回任何 JArray 或 JObject 对象/引用,因此这不应“泄漏”任何 Newtonsoft.Json 依赖项。我没有尝试跨项目将 JObject 转换为 JObject,因此不应发生转换。

我创建了一个小型控制台应用程序

var hostBuilder = new HostBuilder();

var svc = hostBuilder.MyHost.Services.GetService<ApplicationRegistrationService>();

var uris = await svc.GetSpaUris("b3340c1e-c37a-471f-8c90-4e25f27990e8");

这没有这样的铸造问题。因此,SpecflowPlus Runner 使用的 Newtonsoft.Json 版本似乎可能是问题所在。

我返回 astring[]以尝试避免出现依赖交叉问题。

我查看了 Specflow 文档,它说您可以创建一个 specflow.json 配置文件,并且您可以指定“自定义”依赖项。

dependencies custom dependencies Specifies custom dependencies for the SpecFlow runtime. See Plugins for details. Default: not specified

https://docs.specflow.org/projects/specflow/en/latest/Extend/Plugins.md

但是这个链接返回

\          SORRY            /
         \                         /
          \    This page does     /
           ]   not exist yet.    [    ,'|
           ]                     [   /  |
           ]___               ___[ ,'   |
           ]  ]\             /[  [ |:   |
           ]  ] \           / [  [ |:   |
           ]  ]  ]         [  [  [ |:   |
           ]  ]  ]__     __[  [  [ |:   |
           ]  ]  ] ]\ _ /[ [  [  [ |:   |
           ]  ]  ] ] (#) [ [  [  [ :===='
           ]  ]  ]_].nHn.[_[  [  [
           ]  ]  ]  HHHHH. [  [  [
           ]  ] /   `HH("N  \ [  [
           ]__]/     HHH  "  \[__[
           ]         NNN         [
           ]         N/"         [
           ]         N H         [
          /          N            \
         /           q,            \
        /                           \

有人知道我该如何解决吗?自定义依赖是我的救赎吗?如果是这样,有人知道怎么做吗?

标签: specflow

解决方案


自定义依赖项仅用于更改 SpecFlow 的行为。他们与此无关。

SpecFlow+ Runner 在内部使用 Newtonsoft.Json 11。由于测试运行程序中的依赖项无法通过正常的 NuGet 依赖项解决,因此需要随测试运行程序 NuGet 包一起提供。这就是为什么您在将所有项目更新到 v12 时也会看到 v11 程序集的原因。

而且由于在 .NET 中加载程序集,这变得越来越复杂,并且您会收到此错误。

目前我唯一能想到的可以解除阻止的是您也在使用 Newtonsoft.Json v11。我希望这是可能的。

请在https://github.com/SpecFlowOSS/SpecFlow/上打开有关此问题的问题,以便我们查看并修复此问题。


全面披露:我是 SpecFlow 和 SpecFlow+ 的社区经理


推荐阅读