如何忽略单元测试中的程序集引用不匹配?
How do I ignore the assembly reference mismatch in unit tests?
我正在尝试篡改程序集,以便能够模拟不容易被模拟的代码,such as SharePoint assemblies。
作为原型,我有一个解决方案,其中测试代码通过使用 ILRepack 和 Mono.Cecil 的自定义构建操作被篡改,因此实际代码不是最初编写的代码。
当包含测试代码的程序集未签名时,一切正常。签署程序集后,我看到了预期的错误:
The located assembly's manifest definition does not match the assembly reference.
由于程序集被篡改,显然,密钥不相同(如果在篡改后签名)或不存在。
我认为通过 AppDomain.CurrentDomain.AssemblyResolve
事件可以强制接受被篡改的程序集,但事实并非如此。
我如何要求 .NET Framework 在完全信任的单元测试 运行 期间忽略程序集匹配检查,并在它期望对它们进行签名时接受未签名的程序集?
据我了解,问题不在于强名称验证。不仅错误会有所不同,而且 running the corresponding sn –Vr
也没有效果:错误仍然存在。
实际问题似乎出在程序集绑定级别。这也是为什么我惊讶地看到引发了 AppDomain.CurrentDomain.AssemblyResolve
事件,但它的结果仍然被忽略;可能,它并没有像我一直认为的那样。
解决方案比我想象的要简单得多。正如我所猜测的那样,问题不在于强名称验证,而是依赖于 public 密钥令牌的程序集绑定,因此可以在篡改程序集时替换令牌。
第一步是在篡改之前,获取原始public密钥和public密钥令牌。它们都在 AssemblyName
.
内
var originalAssemblyBytes = File.ReadAllBytes(originalFilePath);
var originalAssemblyName = Assembly.Load(originalAssemblyBytes).GetName();
下一步是篡改本身:首先使用 ILRepack 合并两个程序集,然后使用 Mono.Cecil 进行更精细的更改。在第二步中,Mono.Cecil 用于替换 public 密钥和 public 密钥令牌:
var assemblyName = mergedModule.Assembly.Name;
assemblyName.HasPublicKey = true;
assemblyName.PublicKey = originalAssemblyName.GetPublicKey();
assemblyName.PublicKeyToken = originalAssemblyName.GetPublicKeyToken();
必须同时更改两者:如果仅更改令牌,则一旦使用程序集就会抛出“无效程序集public密钥”错误。
这适用于使用 .snk 和 .pfx 签名的两个程序集:因为测试是 运行 完全信任的,所以验证没有完成,这意味着 public 密钥没有'对应私钥无关
我正在尝试篡改程序集,以便能够模拟不容易被模拟的代码,such as SharePoint assemblies。
作为原型,我有一个解决方案,其中测试代码通过使用 ILRepack 和 Mono.Cecil 的自定义构建操作被篡改,因此实际代码不是最初编写的代码。
当包含测试代码的程序集未签名时,一切正常。签署程序集后,我看到了预期的错误:
The located assembly's manifest definition does not match the assembly reference.
由于程序集被篡改,显然,密钥不相同(如果在篡改后签名)或不存在。
我认为通过 AppDomain.CurrentDomain.AssemblyResolve
事件可以强制接受被篡改的程序集,但事实并非如此。
我如何要求 .NET Framework 在完全信任的单元测试 运行 期间忽略程序集匹配检查,并在它期望对它们进行签名时接受未签名的程序集?
据我了解,问题不在于强名称验证。不仅错误会有所不同,而且 running the corresponding sn –Vr
也没有效果:错误仍然存在。
实际问题似乎出在程序集绑定级别。这也是为什么我惊讶地看到引发了 AppDomain.CurrentDomain.AssemblyResolve
事件,但它的结果仍然被忽略;可能,它并没有像我一直认为的那样。
解决方案比我想象的要简单得多。正如我所猜测的那样,问题不在于强名称验证,而是依赖于 public 密钥令牌的程序集绑定,因此可以在篡改程序集时替换令牌。
第一步是在篡改之前,获取原始public密钥和public密钥令牌。它们都在 AssemblyName
.
var originalAssemblyBytes = File.ReadAllBytes(originalFilePath);
var originalAssemblyName = Assembly.Load(originalAssemblyBytes).GetName();
下一步是篡改本身:首先使用 ILRepack 合并两个程序集,然后使用 Mono.Cecil 进行更精细的更改。在第二步中,Mono.Cecil 用于替换 public 密钥和 public 密钥令牌:
var assemblyName = mergedModule.Assembly.Name;
assemblyName.HasPublicKey = true;
assemblyName.PublicKey = originalAssemblyName.GetPublicKey();
assemblyName.PublicKeyToken = originalAssemblyName.GetPublicKeyToken();
必须同时更改两者:如果仅更改令牌,则一旦使用程序集就会抛出“无效程序集public密钥”错误。
这适用于使用 .snk 和 .pfx 签名的两个程序集:因为测试是 运行 完全信任的,所以验证没有完成,这意味着 public 密钥没有'对应私钥无关