缺少方法异常 单元测试

9
在Visual Studio 2017测试运行器中,项目引用似乎存在运行时问题。单元测试CSPROJ使用TargetFramework=net47构建正常,但在执行时,我们从MSTEST或XUNIT收到以下信息。使用Microsoft.NET.Test.Sdk v15.0.0。

测试执行错误(x86):Serilog Seq 扩展

System.MissingMethodException:找不到方法:'Serilog.LoggerConfiguration Serilog.SeqLoggerConfigurationExtensions.Seq(Serilog.Configuration.LoggerSinkConfiguration,System.String,Serilog.Events.LogEventLevel,Int32,System.Nullable<1<System.TimeSpan>>,System.String,System.String,System.Nullable<1,System.Nullable<Int64>,Serilog.Core.LoggingLevelSwitch,System.Net.Http.HttpMessageHandler,System.Nullable<1,Boolean,Int32>)'。

单元测试示例 - Serilog

[Fact]
public void TestMethod1()
{
    LoggerConfiguration loggerConfig = new LoggerConfiguration();    
    loggerConfig.MinimumLevel.Debug();                    
    loggerConfig.WriteTo.LiterateConsole();    
    loggerConfig.WriteTo.Seq("http://localhost:65454");    
}

如果我们引用net462项目,我们会得到相同的结果,因此我们认为这与VS 2017有关,而不是.NET Framework版本。我们从未在VS 2015中看到过这个错误。似乎存在加载带有可选参数/匹配签名等DLL扩展的问题。该方法显然存在,否则它就无法编译——为什么在运行时会崩溃呢?
如果我只使用本地nuget包,它可以正常工作——只有当通过ProjectReference在.NET Core CSPROJ中引用任何项目时,才会出现问题。它似乎不能正确处理依赖树。
另一个例子是使用KeyVault,其中VS Test Runner无法正确找到扩展方法...
测试执行错误(x86):KeyVault Extension
消息: System.MissingMethodException : Method not found: 'Void Microsoft.Azure.KeyVault.KeyVaultClient..ctor(AuthenticationCallback, System.Net.Http.DelegatingHandler[])'。
单元测试示例-KeyVault
[Fact]
public void TestMethod1()
{
    KeyVaultClient _kvClient = new KeyVaultClient(new AuthenticationCallback(getKeyVaultToken));
}

private static async Task<string> getKeyVaultToken(string authority, string resource, string scope)
{
    var authContext = new AuthenticationContext(authority);
    ClientCredential clientCred = new ClientCredential("test", "account");
    AuthenticationResult result = authContext.AcquireTokenAsync(resource, clientCred).Result;

    if (result == null)
        throw new InvalidOperationException("Failed to obtain the JWT token");

    return result.AccessToken;
}
3个回答

14

发现使用 dotnet test 时存在奇怪的问题。运行 dotnet test --diag 并查看输出后,我意识到有更新的 Microsoft.NET.Test.Sdk 版本,而版本 15.0.0 掩盖了实际问题。将 NuGet 升级到 15.3.0-preview-20170502-03 后,出现了不同的异常。

错误来源: Microsoft.Rest.ClientRuntime

System.TypeLoadException: 'Inheritance security rules violated by type: 'System.Net.Http.WebRequestHandler'. Derived types must either match the security accessibility of the base type or be less accessible.'

现在这很有趣 - MissingMethodException 掩盖了实际问题,实际问题深藏在 System.Net.Http 中。第二个认识是,这个基础库中存在一个 bug,阻止类型加载。一旦我更新了 NuGet 中的 System.Net.Http 到版本 4.3.1,问题就消失了,我的项目引用也重新开始工作。

结论

升级到最新的预览版 Microsoft.NET.Test.SDK 和最新版本的 System.Net.Http 可以解决使用 dotnet test 时出现的奇怪的 MissingMethodException 问题。你可以在这里的 github 上追踪这个未解决的问题

选项 #2 - 排除包引用资产

对于最新的 VS 2017 CSPROJ 格式 - 下面的配置也可以修复此问题,因为它会禁止将 System.Net.Http 复制到构建输出路径中,而默认情况下会加载 GAC 版本 4.0.0.0

<PackageReference Include="System.Net.Http" Version="4.3.1">
  <ExcludeAssets>All</ExcludeAssets>
</PackageReference>

选项#3-程序集绑定重定向

dotnet core将遵循您在app.config中设置的任何运行时绑定重定向,因此,对于任何依赖于System.Net.Http版本4.1.*的NuGet依赖项,您可以重定向到最新版本或回退到最后一个稳定版本4.0

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <!-- Another PackageReference dependency binds to 4.1.1 which is busted, we leverage .NET Core redirection and revert to CLR 4.0.0 -->
      <dependentAssembly>
        <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
        <bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="4.0.0.0"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

1
遇到了相同的问题,在PowerShell中出现了“MissingMethodException”...结果发现,如果将System.Net.Http降级为目标版本4.0.0.0(GAC'd),它将恢复新版本中的安全问题。 - SliverNinja - MSFT
1
System.MissingMethodException.NetFramework 项目中仅在 Windows 计算机上导致单元测试失败,但在 Mac 上测试通过。 添加对 Microsoft.NET.Test.SDK 包的引用已为我解决了这个问题。 - foxanna
刚刚花了一整天的时间,试图解决使用VS测试资源管理器运行单元测试时,Azure密钥保管库出现构造函数缺失异常的问题 - 谢谢! - Matt Frear

0

我在测试一个依赖于 Nuget 包的项目中遇到了这个问题,该 Nuget 包已经在被测试的项目中更新,但在测试项目中(缺少方法的源)没有更新。

解决方案就是在测试项目中升级受影响的 Nuget:

Right-Click the test project > Manage Nuget packages > Upgrade necessary packages

0

我正在开发一个SharePoint插件,该插件已安装在我用于开发的服务器上。因此,我认为DLL在GAC中,并且该DLL被首先选中!

我从测试运行器中得到了MissingMethodException。所以我想出了一个简单的解决方法。

更改AssemblyInfo.cs中的版本号!这将使GAC中的版本号与bin / Release目录中的版本号不同,因此测试运行器将使用正确的DLL。太好了!

另请参阅:

System.MissingMethodException: Method not found?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接