TestMethod:异步任务TestSth()不适用于.NET 4.0

时间:2014-03-17 15:25:07

标签: c# unit-testing .net-4.0 async-await mstest

我尝试使用.NET 4.0 BCL Async和MsTest运行异步测试方法。

由于测试用例资源管理器中缺少条目,此设置似乎无法处理 [TestMethod] async 任务 TestSth()。将签名更改为异步 void 后,我可以运行测试用例但结果错误(根本不会报告任何错误)。

我在Running Async Task unit tests with TFS 2010看到了一个问题,但我认为应该有更好的方法来解决这个问题。

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

您只能将async关键字与针对.NET 4.5的MSTest引用类库一起使用。

如果由于某种原因无法使用.NET 4.5,那么您只需要手动等待任务。

即使生产代码(即被测代码)无法使用.NET 4.5,为什么测试项目不能这样做呢?如果您已经可以使用VS 2012+,那么.NET 4.5将安装在您的开发计算机上。

答案 1 :(得分:0)

这是一个适合我的解决方法。弄清楚有点棘手,但最后我的.NET 4.0库中的所有单元测试都被检测到并显示在测试资源管理器中,运行和传递,并且它们都是作为普通async Task方法编写的,没有任何特殊的测试运行器,包装器或第三方依赖项。

  1. 将单元测试项目的目标框架更改为.NET 4.5。
    • 是的,即使项目引用您正在测试目标.NET 4.0,您也必须这样做。
  2. 单元中删除 Microsoft.Bcl Microsoft.Bcl.Build Microsoft.Bcl.Async NuGet程序包引用测试项目。如果您还没有添加这些引用,那么只需将它们添加到您的单元测试项目
  3. System.Runtime.dll System.Threading.Tasks.dll 添加到单元测试项目作为项目中的链接文件&# 39; s根目录。
    1. 在解决方案资源管理器中右键单击单元测试项目
    2. 添加> 现有项目......
    3. 浏览到您的解决方案的软件包文件夹,找到 Microsoft.Bcl net40 软件包文件夹;例如, ... \ packages \ Microsoft.Bcl.1.1.10 \ lib \ net40 \
    4. 在文件类型下拉列表中选择所有文件(*。*)
    5. 按住 Ctrl 键,鼠标左键单击 System.Runtime.dll System.Threading.Tasks.dll 以选择它们。
    6. 点击添加按钮上的小下拉箭头。 (不要单击添加按钮。)
    7. 添加按钮的下拉列表中,点击添加为链接。现在,两个程序集都可以在项目的根目录中看到。
      • 您必须将装配链接保留在项目的根目录中。不要将它们移动到子文件夹。
      • 如果您的项目受源代码管理,那么您可能会注意到这些链接文件被标记为已排除(如果它们不是,则它们应该是。)NuGet packages 文件夹,这些文件所在的位置,不应检入源代码管理。由于它们只是链接文件,因此在恢复NuGet包之后,任何人都应该完全没有问题。
  4. 在解决方案资源管理器中选择两个链接的装配文件( Ctrl +左键单击),或者只是分别对每个文件执行以下步骤。
  5. 右键单击任一选定文件,然后选择属性。将打开属性窗口。
  6. 复制到输出目录字段设置为如果更新则复制。
  7. 您的单元测试项目文件现在应包含类似于以下内容的内容。

    <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
      {根} \包\ Microsoft.Bcl.Build.1.0.21 \建立\ 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.运行项目安装脚本

         

    对于在package 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>