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

Yaa*_*lis 47 asp.net nunit unit-testing vs-web-site-project

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

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

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

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

Bri*_*ite 23

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

  • 打开MVC文件夹"作为一个网站,从本地iis"获得intellisense和调试工作正常
  • 添加一个位于源控制目录中的单元测试项目
  • 向TEST项目添加预构建步骤,因为我们无法将一个步骤添加到作为网站打开的项目中.想象一下网站是\ FooSite,我们的测试项目是\ FooSite.Tests.已编译的应用程序代码将以FooSite.Tests\FooSite_Precompiled\bin结尾.
  • *
<Target Name="BeforeBuild">
     <AspNetCompiler VirtualPath="FooSite" TargetPath="$(ProjectDir)\FooSite_Precompiled" Force="true"
 Debug="true" />   </Target>
Run Code Online (Sandbox Code Playgroud)
  • 在测试项目中添加对FooSite_Precompiled/bin/App_Code.dll的引用.
  • 这就是它的繁荣.你可以吃蛋糕,也可以吃.每次在解决方案中单击Build时,都会调用网站上的aspnet_compiler.ext工具csproj(它仍然存在),与MSBuild不同,它可以编译app_code,而Debug ="true"允许您进入app_code.调试单元测试时的DLL代码.当您运行更新的单元测试时,您只需要构建.当您在页面上查看更改的效果时,您只需更改代码/保存/刷新页面,因为app_code文件夹在从Web服务器调用时动态编译.


Fre*_*örk 19

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


Ed *_*mes 11

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

我们经常使用两种方法:

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

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

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

  • .Net之前版本的dll是一场噩梦.我相信这被昵称为"dll hell".使用.Net这不再是一个问题. (5认同)

bla*_*zee 6

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

  <PropertyGroup>
    <WebsiteName>MyWebsite</WebsiteName>
    <WebsitePath>..</WebsitePath>
  </PropertyGroup>
  <Import Project="$(ProjectDir)\Website.targets" />
  <Target Name="BeforeBuild" DependsOnTargets="CompileWebsite">
  </Target>
Run Code Online (Sandbox Code Playgroud)

你的.csproj,自定义WebsiteName,WebsitePath你应该准备好了.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>
Run Code Online (Sandbox Code Playgroud)