System.MissingMethodException单元测试

Sli*_*SFT 6 mstest xunit .net-core visual-studio-2017 .net-4.7

在Visual Studio 2017测试运行器中看到项目引用似乎是运行时问题.单元测试CSPROJ构建得很好TargetFramework=net47,但在执行时我们从MSTEST或XUNIT获得以下消息.使用Microsoft.NET.Test.Sdkv15.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.Nullable1,System.Nullable 1<Int64>, Serilog.Core.LoggingLevelSwitch, System.Net.Http.HttpMessageHandler, System.Nullable1,Boolean,Int32) ".

单元测试示例 - Serilog

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

如果我们引用net462项目,我们会得到相同的结果,因此我们认为它与VS 2017相关,而不是.NET Framework版本.我们从未在VS 2015中看到过这个错误.似乎有一个问题是加载带有可选参数/匹配签名等的DLL扩展.该方法显然存在或者无法编译 - 为什么在运行时这会崩溃?

如果我只使用本地nuget包它可以正常工作 - 这似乎只是ProjectReference在.NET Core CSPROJ 引用任何项目时出现问题.它似乎没有正确处理依赖树.

使用KeyVaultVS 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;
}
Run Code Online (Sandbox Code Playgroud)

Sli*_*SFT 11

发现这个奇怪的问题dotnet test是双重的.在运行dotnet test --diag并查看输出之后,它让我意识到有哪个版本的新版本Microsoft.NET.Test.Sdk15.0.0掩盖了真正的问题.一旦我将nuget升级到15.3.0-preview-20170502-03,就会出现另一个异常.

错误源:Microsoft.Rest.ClientRuntime

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

现在这很有趣 - 它MissingMethodException掩盖了埋藏在其中的真正问题System.Net.Http.第二个实现是这个基础库有一个错误,可以防止加载类型.一旦我更新System.Net.Http到版本4.3.1,问题就消失了,我的项目参考再次开始工作.

结论

更新Microsoft.NET.Test.SDK到最新预览System.Net.Http最新版本,MissingMethodException通过dotnet测试获得过去的奇怪.您可以在此处跟踪github上的未解决问题.

选项#2 - 排除包参考资产

对于最新的VS 2017 CSPROJ格式 - 以下配置也修复此问题,因为它会禁止复制System.Net.HttpBuild Output路径,该路径默认加载GAC的版本4.0.0.0.

<PackageReference Include="System.Net.Http" Version="4.3.1">
  <ExcludeAssets>All</ExcludeAssets>
</PackageReference>
Run Code Online (Sandbox Code Playgroud)

选项#3 - 装配绑定重定向

dotnetcore将遵循您放置在您的任何运行时绑定重定向app.config,因此您必须System.Net.Http对版本进行任何nuget依赖4.1.*,您可以重定向到最新版本或恢复到上一个​​稳定版本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>
Run Code Online (Sandbox Code Playgroud)