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

时间:2022-12-23 08:10:19

I have an ASP.net Web Site Project (.net 3.5). Currently all of the non-code behind code files (including Linq2Sql stuff, data contexts, business logic, extension methods, etc) are located in the App_Code folder.

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

I am interested in introducing Unit Testing (using nunit) in at least some sections of the project moving forward. Any Unit Testing that I would be doing would need to have full access to all of the code that is currently located in the App_Code folder. I have done some initial reading so far, and the consensus seems to be:

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

  • This will not be possible given my current setup
  • 考虑到我目前的设置,这是不可能的
  • Unit testing requires referencing classes that are part of a compiled dll, and a Web Site Project by definition only compiles at run time.
  • 单元测试需要引用作为已编译dll的一部分的类,并且根据定义,Web站点项目仅在运行时进行编译。
  • In order to proceed, I will need to either convert my entire project to a Web Application, or move all of the code that I would like to test (ie: the entire contents of App_Code) to a class library project and reference the class library project in the web site project. Either of these will provide access to the classes that I need in compiled dll format, which will allow me to Unit Test them.
  • 为了继续进行,我需要我的整个项目转换为一个Web应用程序,或移动的所有代码,我想测试(即:App_Code的全部内容)一个类库项目,引用类库项目的网站项目。其中任何一个都将提供对我需要的编译dll格式的类的访问,这将允许我对它们进行单元测试。

Is this correct? Or is there another way that I can Unit Test without restructuring/refactoring my entire project?

这是正确的吗?或者有其他方法可以在不重组/重构整个项目的情况下进行单元测试吗?

8 个解决方案

#1


18  

Your conclusions seem correct. I would vote for moving functionality into one or several class library projects, since that may open the door for reusing the same functionality in other projects as well.

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

#2


21  

My shop has finally worked through an answer for this for our MVC project. And I want to share it as I chased a lot of dead ends here on * hearing a lot of people say it couldn't be done. We do it like this:

我的商店终于为我们的MVC项目找到了答案。我想分享它因为我在*上追了很多死角听到很多人说这是不可能的。我们这样做:

  • Open the MVC folder "as a website, from local iis" which gets intellisense and debugging working properly
  • 打开MVC文件夹“作为一个网站,从本地iis”获得智能感知和调试正常工作
  • Add a unit test project that lives in our source controlled directory
  • 添加位于源代码控制目录中的单元测试项目
  • Add a pre-build step to the TEST project, since we can't add one to a project that is open as a website. Imagine website is \FooSite and our test project is \FooSite.Tests. The compiled app code will end up in FooSite.Tests\FooSite_Precompiled\bin.
  • 向测试项目添加一个预构建步骤,因为我们不能向作为网站开放的项目添加一个。想象网站是\FooSite,我们的测试项目是\FooSite. tests。编译后的应用程序代码最终会出现在foo站点。test \ foosite_precompile \bin。
  • *
<Target Name="BeforeBuild">
     <AspNetCompiler VirtualPath="FooSite" TargetPath="$(ProjectDir)\FooSite_Precompiled" Force="true"
 Debug="true" />   </Target>
  • Add a reference to the FooSite_Precompiled/bin/App_Code.dll in your test project.
  • 添加对foosite_precompile /bin/App_Code的引用。测试项目中的dll。
  • Boom that's it. You can have your cake and eat it too. Every time you click Build in your solution you call the aspnet_compiler.ext tool on your website csproj (which does still exist) which is able, unlike MSBuild, to compile app_code, and the Debug="true" allows you step into the app_code.dll code when debugging your unit test. And you only need to Build when you're running updated unit tests. When you're looking at the effects of your change on the page, you just Change Code/Save/Refresh Page since the app_code folder dynamically compiles when called from your web server.
  • 繁荣的。你也可以吃你的蛋糕。每次单击解决方案中的Build时,都调用aspnet_compiler。与MSBuild不同,csproj网站上的ext工具可以编译app_code, Debug="true"允许您进入app_code。调试单元测试时的dll代码。您只需要在运行更新的单元测试时构建。当您查看更改对页面的影响时,您只需更改代码/保存/刷新页面,因为app_code文件夹在从您的web服务器调用时动态编译。

#3


11  

We have this issue at my company (My boss doesn't like DLLs, some rubbish about versioning...)

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

We have two ways round it that we use frequently:

我们有两种常用的方法:

1) Get the CI tool to do the unit testing: We use TeamCity which has a pretty tight NUnit integration, and our solution builds quick enough (and has few enough tests) for this to be a valid option.

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

2) Manually precompile and unit test the resulting binaries: It's perfectly possible to run the ASP.net compiler / MSBuild from the command line (as if you were doing a 'Publish' build) and just unit test the resulting binaries.

2)手动预编译和单元测试产生的二进制文件:从命令行运行ASP.net编译器/ MSBuild是完全有可能的(就像你在做一个“发布”构建),并且只对结果的二进制文件进行单元测试。

However, if you have the option of segregating the code into binaries (class libraries) or just using a web application, I'd suggest that as a better alternative.

但是,如果您可以选择将代码分割成二进制(类库),或者仅仅使用web应用程序,我建议您将其作为更好的选择。

#4


6  

Should anyone find themselves implementing Brian's solution, here's a Website.targets file you can include in unit testing solution. It (re)compiles website only when App_Code changes. Just add something like

如果有人发现自己正在实施布莱恩的解决方案,这里有一个网站。目标文件可以包含在单元测试解决方案中。它只在App_Code更改时编译网站。只需添加类似

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

to your .csproj, customizing WebsiteName and WebsitePath and you should be ready to go. Website.targets:

对于你的。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>

#5


2  

It looks like this is possible whilst still using App_code, but I would either move this logic out to its own class library project or change the project type to Web Application, as Fredrik and Colin suggest.

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

I always create my own ASP.NET projects as Web Application projects not Websites.

我总是创建我自己的ASP。NET项目作为Web应用程序项目而不是网站。

#6


1  

And as the OP stated it's also possible to move to a Web App project, which i would say is cleaner as well, your pages can stay in the wep app project, you will have them in 1 DLL (testable). All your business logic etc. goes in a separate class library / libraries.

正如OP所指出的,移动到一个Web应用程序项目也是可能的,我想说的是更简洁,你的页面可以保留在wep应用程序项目中,你将在一个DLL中拥有它们(可测试)。所有的业务逻辑等等都放在一个单独的类库/库中。

#7


0  

It is possible to unit test classes stored in the App_Code folder without converting your project to a Web App or moving your classes to a Class Library project.

可以在App_Code文件夹中存储单元测试类,而无需将项目转换为Web应用程序或将类转移到类库项目。

All that is necessary is setting the code files' Build Actions to Compile. This will cause Debugging and Unit Testing your website to output a .dll file.

所需要做的就是设置要编译的代码文件的构建操作。这将导致调试和单元测试您的网站输出一个。dll文件。

Now when you reference your website project from the unit test project, the classes in the app_code folder will be visible.

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

NOTE:

注意:

Setting your .cs files' Build Action to Compile will cause your website to generate a .dll file on debugging and unit-testing. The .dll file will cause problems when you debug your website because IIS will now find your code in two places, the bin and the App_Code folder and will not know which one to use. I currently just delete the .dll file when I want to debug.

将.cs文件的构建操作设置为编译将导致您的网站在调试和单元测试中生成一个.dll文件。当您调试您的网站时,.dll文件将会引起问题,因为IIS现在会在bin和App_Code文件夹中找到您的代码,而不知道使用哪个文件夹。我目前只是删除。dll文件时,我想要调试。

#8


0  

I had to change Brian White's solution by adding the PhysicalPath attribute. In addition I am not using the Default Web Site and had to change the VirtualPath property to my website name.

我必须通过添加物理路径属性来更改Brian White的解决方案。此外,我没有使用默认的Web站点,必须将VirtualPath属性更改为我的站点名称。

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

The resulting dll will be at MySite_Precompiled\App_Code.dll

生成的dll将位于mysite_precompile \App_Code.dll处

#1


18  

Your conclusions seem correct. I would vote for moving functionality into one or several class library projects, since that may open the door for reusing the same functionality in other projects as well.

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

#2


21  

My shop has finally worked through an answer for this for our MVC project. And I want to share it as I chased a lot of dead ends here on * hearing a lot of people say it couldn't be done. We do it like this:

我的商店终于为我们的MVC项目找到了答案。我想分享它因为我在*上追了很多死角听到很多人说这是不可能的。我们这样做:

  • Open the MVC folder "as a website, from local iis" which gets intellisense and debugging working properly
  • 打开MVC文件夹“作为一个网站,从本地iis”获得智能感知和调试正常工作
  • Add a unit test project that lives in our source controlled directory
  • 添加位于源代码控制目录中的单元测试项目
  • Add a pre-build step to the TEST project, since we can't add one to a project that is open as a website. Imagine website is \FooSite and our test project is \FooSite.Tests. The compiled app code will end up in FooSite.Tests\FooSite_Precompiled\bin.
  • 向测试项目添加一个预构建步骤,因为我们不能向作为网站开放的项目添加一个。想象网站是\FooSite,我们的测试项目是\FooSite. tests。编译后的应用程序代码最终会出现在foo站点。test \ foosite_precompile \bin。
  • *
<Target Name="BeforeBuild">
     <AspNetCompiler VirtualPath="FooSite" TargetPath="$(ProjectDir)\FooSite_Precompiled" Force="true"
 Debug="true" />   </Target>
  • Add a reference to the FooSite_Precompiled/bin/App_Code.dll in your test project.
  • 添加对foosite_precompile /bin/App_Code的引用。测试项目中的dll。
  • Boom that's it. You can have your cake and eat it too. Every time you click Build in your solution you call the aspnet_compiler.ext tool on your website csproj (which does still exist) which is able, unlike MSBuild, to compile app_code, and the Debug="true" allows you step into the app_code.dll code when debugging your unit test. And you only need to Build when you're running updated unit tests. When you're looking at the effects of your change on the page, you just Change Code/Save/Refresh Page since the app_code folder dynamically compiles when called from your web server.
  • 繁荣的。你也可以吃你的蛋糕。每次单击解决方案中的Build时,都调用aspnet_compiler。与MSBuild不同,csproj网站上的ext工具可以编译app_code, Debug="true"允许您进入app_code。调试单元测试时的dll代码。您只需要在运行更新的单元测试时构建。当您查看更改对页面的影响时,您只需更改代码/保存/刷新页面,因为app_code文件夹在从您的web服务器调用时动态编译。

#3


11  

We have this issue at my company (My boss doesn't like DLLs, some rubbish about versioning...)

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

We have two ways round it that we use frequently:

我们有两种常用的方法:

1) Get the CI tool to do the unit testing: We use TeamCity which has a pretty tight NUnit integration, and our solution builds quick enough (and has few enough tests) for this to be a valid option.

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

2) Manually precompile and unit test the resulting binaries: It's perfectly possible to run the ASP.net compiler / MSBuild from the command line (as if you were doing a 'Publish' build) and just unit test the resulting binaries.

2)手动预编译和单元测试产生的二进制文件:从命令行运行ASP.net编译器/ MSBuild是完全有可能的(就像你在做一个“发布”构建),并且只对结果的二进制文件进行单元测试。

However, if you have the option of segregating the code into binaries (class libraries) or just using a web application, I'd suggest that as a better alternative.

但是,如果您可以选择将代码分割成二进制(类库),或者仅仅使用web应用程序,我建议您将其作为更好的选择。

#4


6  

Should anyone find themselves implementing Brian's solution, here's a Website.targets file you can include in unit testing solution. It (re)compiles website only when App_Code changes. Just add something like

如果有人发现自己正在实施布莱恩的解决方案,这里有一个网站。目标文件可以包含在单元测试解决方案中。它只在App_Code更改时编译网站。只需添加类似

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

to your .csproj, customizing WebsiteName and WebsitePath and you should be ready to go. Website.targets:

对于你的。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>

#5


2  

It looks like this is possible whilst still using App_code, but I would either move this logic out to its own class library project or change the project type to Web Application, as Fredrik and Colin suggest.

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

I always create my own ASP.NET projects as Web Application projects not Websites.

我总是创建我自己的ASP。NET项目作为Web应用程序项目而不是网站。

#6


1  

And as the OP stated it's also possible to move to a Web App project, which i would say is cleaner as well, your pages can stay in the wep app project, you will have them in 1 DLL (testable). All your business logic etc. goes in a separate class library / libraries.

正如OP所指出的,移动到一个Web应用程序项目也是可能的,我想说的是更简洁,你的页面可以保留在wep应用程序项目中,你将在一个DLL中拥有它们(可测试)。所有的业务逻辑等等都放在一个单独的类库/库中。

#7


0  

It is possible to unit test classes stored in the App_Code folder without converting your project to a Web App or moving your classes to a Class Library project.

可以在App_Code文件夹中存储单元测试类,而无需将项目转换为Web应用程序或将类转移到类库项目。

All that is necessary is setting the code files' Build Actions to Compile. This will cause Debugging and Unit Testing your website to output a .dll file.

所需要做的就是设置要编译的代码文件的构建操作。这将导致调试和单元测试您的网站输出一个。dll文件。

Now when you reference your website project from the unit test project, the classes in the app_code folder will be visible.

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

NOTE:

注意:

Setting your .cs files' Build Action to Compile will cause your website to generate a .dll file on debugging and unit-testing. The .dll file will cause problems when you debug your website because IIS will now find your code in two places, the bin and the App_Code folder and will not know which one to use. I currently just delete the .dll file when I want to debug.

将.cs文件的构建操作设置为编译将导致您的网站在调试和单元测试中生成一个.dll文件。当您调试您的网站时,.dll文件将会引起问题,因为IIS现在会在bin和App_Code文件夹中找到您的代码,而不知道使用哪个文件夹。我目前只是删除。dll文件时,我想要调试。

#8


0  

I had to change Brian White's solution by adding the PhysicalPath attribute. In addition I am not using the Default Web Site and had to change the VirtualPath property to my website name.

我必须通过添加物理路径属性来更改Brian White的解决方案。此外,我没有使用默认的Web站点,必须将VirtualPath属性更改为我的站点名称。

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

The resulting dll will be at MySite_Precompiled\App_Code.dll

生成的dll将位于mysite_precompile \App_Code.dll处