单元测试ASP.net网站项目代码存储在App_Code中

时间:2009-07-29 07:29:01

标签: asp.net unit-testing nunit web-site-project

我有一个ASP.net网站项目(.net 3.5)。目前,代码文件背后的所有非代码(包括Linq2Sql内容,数据上下文,业务逻辑,扩展方法等)都位于App_Code文件夹中。

我有兴趣在项目的至少某些部分中引入单元测试(使用nunit)。我要做的任何单元测试都需要完全访问当前位于App_Code文件夹中的所有代码。到目前为止,我已经做了一些初步阅读,而且共识似乎是:

  • 根据我目前的设置
  • ,这是不可能的
  • 单元测试需要引用属于已编译dll的类,并且Web站点项目按定义仅在运行时编译。
  • 为了继续,我需要将我的整个项目转换为Web应用程序,或者将我想要测试的所有代码(即:App_Code的全部内容)移动到类库项目和引用网站项目中的类库项目。这些中的任何一个都将提供对编译的dll格式所需的类的访问,这将允许我对它们进行单元测试。

这是对的吗?或者还有另一种方法可以在不重组/重构整个项目的情况下进行单元测试吗?

8 个答案:

答案 0 :(得分:23)

我的商店终于为我们的MVC项目找到了答案。我想分享它,因为我在StackOverflow上追逐了很多死胡同,听到很多人说它无法完成。我们这样做:

  
      
  • 打开MVC文件夹“作为网站,从本地iis”获取智能感知并调试正常工作
  •   
  • 添加位于源控制目录中的单元测试项目
  •   
  • 向TEST项目添加预构建步骤,因为我们无法将其添加到作为网站打开的项目中。想象一下网站是\ FooSite和   我们的测试项目是\ FooSite.Tests。编译的应用程序代码将结束   在FooSite.Tests \ FooSite_Precompiled \ bin。
  •   *   
<Target Name="BeforeBuild">
     <AspNetCompiler VirtualPath="FooSite" TargetPath="$(ProjectDir)\FooSite_Precompiled" Force="true"
 Debug="true" />   </Target>
  
      
  • 在测试项目中添加对FooSite_Precompiled / bin / App_Code.dll的引用。
  •   
  • 这就是它。你可以吃蛋糕,也可以吃。每次单击解决方案中的Build时,都会调用aspnet_compiler.ext工具   在你的网站上csproj(它仍然存在)能够,不像   MSBuild,编译app_code,Debug =“true”允许你步骤   在调试单元测试时进入app_code.dll代码。你呢   只有在运行更新的单元测试时才需要构建。什么时候   您正在查看您的更改对页面的影响   自app_code文件夹动态更改代码/保存/刷新页面   从您的Web服务器调用时进行编译。
  •   

答案 1 :(得分:18)

你的结论似乎是正确的。我会投票将功能转移到一个或多个类库项目中,因为这可能会为在其他项目中重用相同的功能打开大门。

答案 2 :(得分:11)

我们公司有这个问题(我的老板不喜欢DLL,有些关于版本控制的垃圾......)

我们经常使用两种方法:

1)获取CI工具进行单元测试:我们使用TeamCity,它具有非常紧密的NUnit集成,并且我们的解决方案构建得足够快(并且没有足够的测试),因此这是一个有效的选项。

2)手动预编译并对生成的二进制文件进行单元测试:完全可以从命令行运行ASP.net编译器/ MSBuild(就像你正在进行'发布'构建一样)并且只对生成的二进制文件进行单元测试。

但是,如果您可以选择将代码分隔为二进制文件(类库)或仅使用Web应用程序,我建议您将其作为更好的替代方案。

答案 3 :(得分:6)

如果有人发现自己实施了Brian的解决方案,这里有一个可以包含在单元测试解决方案中的Website.targets文件。它(重新)仅在App_Code更改时编译网站。只需添加类似

的内容
  <PropertyGroup>
    <WebsiteName>MyWebsite</WebsiteName>
    <WebsitePath>..</WebsitePath>
  </PropertyGroup>
  <Import Project="$(ProjectDir)\Website.targets" />
  <Target Name="BeforeBuild" DependsOnTargets="CompileWebsite">
  </Target>

到您的.csproj,自定义WebsiteNameWebsitePath,您应该准备好了。 Website.targets:

<?xml version="1.0" encoding="utf-8"?>
<!--
    Target that compiles Website's App_Code to be used for testing
  -->
<Project DefaultTargets="CompileWebsite" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <AppCodeFiles Include="$(WebsitePath)\$(WebsiteName)\App_Code\**\*.*" />
  </ItemGroup>
  <Target Name="CompileWebsite" Inputs="@(AppCodeFiles)" Outputs="$(ProjectDir)\PrecompiledWeb\bin\App_Code.dll">
    <AspNetCompiler VirtualPath="$(WebsiteName)" PhysicalPath="$(WebsitePath)\$(WebsiteName)" TargetPath="$(ProjectDir)\PrecompiledWeb" Force="true" Debug="true" />
  </Target>
  <Target Name="CleanWebsite">
    <RemoveDir Directories="$(WebsitePath)\$(WebsiteName)\PrecompiledWeb" />
  </Target>  
</Project>

答案 4 :(得分:2)

看起来这仍然可以使用App_code,但是我会将这个逻辑移到它自己的类库项目中,或者将项目类型更改为Web应用程序,就像Fredrik和Colin所说的那样。

我总是将自己的ASP.NET项目创建为Web应用程序项目而不是Websites。

答案 5 :(得分:1)

正如OP所说,也可以转移到Web App项目,我认为它也更干净,你的页面可以保留在wep app项目中,你将它们放在1个DLL中(可测试)。您的所有业务逻辑等都位于单独的类库/库中。

答案 6 :(得分:0)

可以对存储在App_Code文件夹中的测试类进行单元化,而无需将项目转换为Web App或将类移动到类库项目。

所有必要的是设置代码文件'Build Actions to Compile。这将导致您的网站的调试和单元测试输出.dll文件。

现在,当您从单元测试项目引用您的网站项目时,app_code文件夹中的类将可见。

注:

将.cs文件“git reflog设置为Build Action会导致您的网站在调试和单元测试时生成.dll文件。调试网站时,.dll文件会导致问题,因为IIS现在会在两个位置找到您的代码,即bin和App_Code文件夹,并且不知道要使用哪个。我当前只是想在调试时删除.dll文件。

答案 7 :(得分:0)

我必须通过添加PhysicalPath属性来更改Brian White的解决方案。另外,我没有使用Default Web Site,必须将VirtualPath属性更改为我的网站名称。

<Target Name="BeforeBuild">
    <AspNetCompiler VirtualPath="myIISsitename.com" PhysicalPath="$(SolutionDir)MySiteFolder" TargetPath="$(ProjectDir)\MySite_Precompiled" Force="true" Debug="true" />
</Target>

生成的dll将位于MySite_Precompiled\App_Code.dll