【问题标题】:System.MissingMethodException Unit TestSystem.MissingMethodException 单元测试
【发布时间】:2017-10-08 00:14:56
【问题描述】:

在 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.Nullable1<System.TimeSpan>, System.String, System.String, System.Nullable1, System.Nullable 1<Int64>, Serilog.Core.LoggingLevelSwitch, System.Net.Http.HttpMessageHandler, System.Nullable1,布尔值,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 包,它可以正常工作 - 这似乎只是在 .NET Core CSPROJ 中通过 ProjectReference 引用任何项目时出现问题。它似乎没有正确处理依赖树。

另一个使用 KeyVault 的示例,其中 VS Test Runner 无法正确找到扩展方法...

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

消息:System.MissingMethodException:找不到方法:'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;
}

【问题讨论】:

    标签: .net-core mstest visual-studio-2017 xunit .net-4.7


    【解决方案1】:

    发现dotnet test 的这个奇怪问题有两个方面。在运行dotnet test --diag 并查看输出后,我意识到newer releases of Microsoft.NET.Test.Sdk 是哪个版本15.0.0 掩盖了真正的问题。一旦我将 nuget 升级到 15.3.0-preview-20170502-03,就会出现一个不同的异常。

    错误来源:Microsoft.Rest.ClientRuntime

    System.TypeLoadException:'类型违反了继承安全规则:'System.Net.Http.WebRequestHandler'。派生类型必须与基类型的安全可访问性相匹配,或者难以访问。'

    现在这很有趣 - MissingMethodException 掩盖了隐藏在 System.Net.Http 中的真正问题。第二个实现是这个base library has a bug which prevents the type from being loaded。一旦我nuget updated System.Net.Http to version 4.3.1,问题就消失了,我的项目参考又开始工作了。

    结论

    更新Microsoft.NET.Test.SDK to latest previewSystem.Net.Http to latest version 以通过dotnet 测试 克服奇怪的MissingMethodException。你可以track the open issue on github here

    选项 #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 核心将遵循您在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>
    

    【讨论】:

    • 在 powershell 中有同样的问题MissingMethodException...事实证明,如果您将System.Net.Http 降级到目标版本4.0.0.0(GAC'd),它将在较新版本中恢复安全问题。
    • System.MissingMethodException.NetFramework 项目中的单元测试仅在 Windows 机器上失败,在 Mac 上它们完美通过。添加对 Microsoft.NET.Test.SDK 打包的引用已经解决了我的问题。
    • 刚刚花了一天时间试图找出 Azure Key Vault 在使用 VS 测试资源管理器运行单元测试时因缺少构造函数的方法异常而失败的相同问题 - 谢谢!
    【解决方案2】:

    我在测试一个项目中的一个类时遇到了这个问题,该项目依赖于一个 Nuget 包,该包已在正在测试的项目中更新,但不在测试项目中(这是缺少方法的来源)。

    解决方案就像在测试项目中升级受影响的 Nuget 一样简单:

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

    【讨论】:

      【解决方案3】:

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

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

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

      另见:

      System.MissingMethodException: Method not found?

      【讨论】:

        猜你喜欢
        • 2020-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-08
        • 1970-01-01
        • 1970-01-01
        • 2011-07-07
        • 2011-04-12
        相关资源
        最近更新 更多