这是一个对我有用的解决方法。弄清楚有点棘手,但最终所有针对我的 .NET 4.0 库的单元测试都被检测到并显示在测试资源管理器中,运行和通过,它们都按照正常的async Task 方法编写,没有任何特殊测试运行器、包装器或第三方依赖项。
- 将单元测试项目的目标框架更改为 .NET 4.5。
- 是的,即使项目引用您正在测试的目标是 .NET 4.0,您也必须这样做。
- 从您的单元中删除 Microsoft.Bcl、Microsoft.Bcl.Build 和 Microsoft.Bcl.Async NuGet 包引用测试项目。如果您还没有添加这些引用,那么只需不要将它们添加到您的单元测试项目。
- 将 System.Runtime.dll 和 System.Threading.Tasks.dll 作为项目根目录中的链接文件添加到您的 单元测试项目目录。
- 在解决方案资源管理器中用鼠标右键单击您的单元测试项目。
-
添加 > 现有项目...
- 浏览到解决方案的包文件夹并找到 Microsoft.Bcl 的 net40 包文件夹;例如,...\packages\Microsoft.Bcl.1.1.10\lib\net40\
- 在文件类型下拉菜单中选择所有文件 (*.*)。
- 按住 Ctrl 键,鼠标左键单击 System.Runtime.dll 和 System.Threading.Tasks.dll 以选择它们。
- 点击添加按钮上的小下拉箭头。 (不要点击添加按钮。)
- 在添加按钮的下拉菜单中,点击添加为链接。这两个程序集现在都在项目的根目录中可见。
- 您必须将程序集链接保留在项目的根目录中。不要将它们移动到子文件夹中。
- 如果您的项目受源代码控制,那么您可能会注意到这些链接文件被标记为已排除(如果不是,它们应该是。) NuGet packages 文件夹,其中这些文件驻留,不应签入源代码管理。由于它们只是链接文件,因此任何人在还原其 NuGet 包后拉下您的更改都应该没有问题。
- 在解决方案资源管理器中选择两个链接的程序集文件(Ctrl + 左键单击)或简单地分别对每个文件执行以下步骤。
- 用鼠标右键单击任一选定文件并选择属性。 属性窗口打开。
- 将复制到输出目录字段设置为如果更新则复制。
您的单元测试项目文件现在应该包含类似于以下内容的内容。
<ItemGroup>
<Content Include="..\..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.Runtime.dll">
<Link>System.Runtime.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.Threading.Tasks.dll">
<Link>System.Threading.Tasks.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
就是这样!
请记住,您的单元测试项目以 .NET 4.5(或更高版本,如果您愿意)为目标,因此单元测试可以使用 async 方法和任何其他 .NET 4.5 功能。与您正在测试的 .NET 4.0 程序集不应该有任何冲突,但如果您确实发现了冲突,可能是因为您为较新的 Framework/C# 功能重新定义了某些类型并将它们公开,因此在您尝试在单元测试中使用这些相同的类型。最好的解决方案是简单地将这些类型设置为您正在测试的项目的内部。
编辑:
完成这些步骤后,您可能会收到一些构建警告:
所有引用 My.csproj 的项目都必须安装 nuget 包 Microsoft.Bcl.Build。如需更多信息,请参阅http://go.microsoft.com/fwlink/?LinkID=317569
{root}\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets
为避免这些警告,只需编辑 单元测试项目 并将以下元数据元素添加到每个项目引用中,该引用指向引用 Microsoft.Bcl.Build 的项目.
<Properties>SkipValidatePackageReferences=true</Properties>
例如:
<ProjectReference Include="..\pcl\pcl.csproj">
<Project>{664a9e98-fac7-4567-a046-0dde95fddb48}</Project>
<Name>pcl</Name>
<Properties>SkipValidatePackageReferences=true</Properties>
</ProjectReference>
完整的解释可以在 Microsoft.Bcl.Build 包中注明的 .targets 文件中找到。为了您的方便,这是完整的评论。
BclBuildValidateNugetPackageReferences
此目标验证当前项目中安装的任何 Nuget 包也安装在项目中
引用当前项目。
这是必要的,因为 Nuget 包包含的不仅仅是简单的引用。安装包确保
1. 添加了目标框架的正确引用集
2. 应用配置文件转换
3.项目安装脚本运行
对于在 packages config 中列出的为当前项目安装的所有包,如果包 ID 与 @(ValidatePackages) 中指定的匹配,请确保在引用项目中安装相同的包。
可以通过为参考设置 SkipValidatePackageReferences=true 来为项目参考禁用此目标:
<ProjectReference Include="..\pcl\pcl.csproj">
<Project>{664a9e98-fac7-4567-a046-0dde95fddb48}</Project>
<Name>pcl</Name>
<Properties>SkipValidatePackageReferences=true</Properties>
</ProjectReference>
可以通过添加以下内容来禁用对项目的所有引用的此目标:
<PropertyGroup>
<SkipValidatePackageReferences>true</SkipValidatePackageReferences>
</PropertyGroup>