5

I want to create an ASP.Net Web Application, and I want to write unit tests for it. But my unit test project can't see any of the types in my web application's App_Code directory.

Steps to reproduce

(skip down past the images if you already know how to create a default webforms web application and add an app_code folder)

Open Visual Studio. Choose File->New->Project.
Choose Templates -> Visual C# -> Web. Choose ASP.Net Web Application. Choose "OK".

enter image description here

Choose "Web Forms". Check "Add unit tests". Click OK.

enter image description here

In the solution explorer, right-click on the web application and choose "Add -> Add ASP.Net Folder -> App_Code".

enter image description here enter image description here

Add a new item to App_Code, named "Util.cs". Add a function to the file so the contents are:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WebApplication1.App_Code
{
    public class Util
    {
        public static int getMeaningOfLife()
        {
            return 42;
        }
    }
}

In the Unit Testing project, change UnitTest1.cs to:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace WebApplication1.Tests
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            int result = WebApplication1.App_Code.Util.getMeaningOfLife();
            if (result != 42)
            {
                Assert.Fail();
            }
        }
    }
}

Then build the project.

Expected behavior:

The solution should build. If we attempt to test, the test should succeed.

Actual behavior:

The solution fails to build with The type or namespace name 'App_Code' does not exist in the namespace 'WebApplication1' (are you missing an assembly reference?)

Other notes

I looked at Unit Testing ASP.net Web Site Project code stored in App_Code, but I don't think the problem exactly matches my circumstances because they're testing a website and I'm testing a web application. Some answers specifically suggest switching to a web application, implying that it would no longer be a problem:

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.

 

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.

 

And as the OP stated it's also possible to move to a Web App project, which i would say is cleaner as well

The advice "try using a web application" doesn't apply to me, because I'm already using a web application, and it still doesn't work.

The answers also suggest "Try moving the code out to its own project", and I do expect that would work, but in my actual solution I have dozens of files in the App_Code directory. I would prefer not to perform any serious structural changes before I can establish a testing framework first.

Community
  • 1
  • 1
Kevin
  • 74,910
  • 12
  • 133
  • 166
  • Did you add a reference to the web project in the Unit Testing project? – JuanR Mar 02 '17 at 16:44
  • You don't need an App_Code directory in a web application. That's for a website project. – mason Mar 02 '17 at 16:49
  • 3
    App_Code is special folder, it will not get compiled in your assembly, but instead will be compiled at run-time by asp.net. So you cannot reference it from unit test, and actually you cannot use it even from your web application assembly (from global.asax for example). So - just don't put anything in that folder unless you know what you are doing and why. – Evk Mar 02 '17 at 16:51
  • @Juan, I tried, but web applications are not visible in the "Projects" panel of the Add Reference window, and AFAIK web applications don't compile to dlls, so I can't add a reference using the "browse" panel either. – Kevin Mar 02 '17 at 16:55
  • But if you _do know_ why are you putting your code in App_Code, and you are sure it should be there, and you sure you want to unit test it - reasonable solution is provided at your linked question here http://stackoverflow.com/a/10386480/5311735. Though I really doubt there is valid reason to do so nowadays. – Evk Mar 02 '17 at 17:04
  • @Evk, that's informative, thanks. I don't know why we keep our .cs files in App_Code. That's just the way the project has been structured since before I started working here five years ago. Strangely, in my non-MCVE solution, I _can_ use classes declared in app_code in global.asax etc. I have no idea how this is possible given what you've said and what I've read elsewhere. – Kevin Mar 02 '17 at 17:08
  • 1
    If you want to use App_Code files as regular files, without their intended purpose (asp.net runtime compilation) - just right click your Util.cs file under App_Code, select Properties and change Build Action from "Content" to "Compile". Then you will be able to reference it everywhere, including unit test. There is nothing magical really in that folder name. – Evk Mar 02 '17 at 17:13
  • @Kevin The code files in your `App_Code` are likely set to `Compile` _and_ the Namespace is the same as your app. If you look at some other "special folder" in ASP.net, like `App_Start`, you'll find similar...hth – EdSF Mar 02 '17 at 17:13
  • I agree with @Evk. It sounds like the web forms template does not include the app_code files in the compilation so you may have to switch the build action on them for the code to get compiled. – JuanR Mar 02 '17 at 17:38

1 Answers1

3

So to bring a bit more clarity. App_Code folder has special meaning in asp.net projects. You can put files there and asp.net will compile them at runtime and will monitor them for changes to recompile on the fly when something changes. Details are not very relevant, main thing is: if you don't need this feature - don't use App_Code folder.

However, there is nothing magical in that folder itself. When you create it via "Add ASP.NET folder" (or just manually in web site project) - Visual Studio will set build action of files you add there to Content, even for code files. Such files will not be compiled into resulting assembly, that is why you cannot use them from your Unit Test project, nor you can use it even from web site code itself. If you manually change build action to Compile - it will be compiled and can be used as usual. That's all the difference.

Evk
  • 98,527
  • 8
  • 141
  • 191
  • I believe this accurately answers the question as I have posed it. I see that if I move my `util.cs` file to anywhere else in the project, then I can properly unit test it. I'm still seeing some peculiar behavior in the non-mcve project I haven't shared here, but I suspect that's an unrelated issue, and would deserve its own post separate from this one. Case closed on this particular issue. – Kevin Mar 02 '17 at 18:11
  • 1
    Note you can move it OR change build action to compile for it to work as you expect. – Evk Mar 02 '17 at 18:12
  • Even if you're using Web Forms, you only need App_Code if you're doing a website (instead of web application). It's even possible to do an MVC website and put all your controllers etc in App_Code. So it's nothing special to do with Web Forms. – mason Mar 02 '17 at 19:31
  • @mason that's right, I removed that. Though I have only even seens this to be used in old web forms projects, never in mvc ones. – Evk Mar 02 '17 at 19:36
  • @Evk Well if you move it, and it's not set as compile, then you need to set it to compile. So really the solution is "set it to compile, and it'd be better not to put it in App_Code so you avoid confusion". And yeah, I was just learning MVC when I tried to put it in a website project instead of web application. It's not something I recommend trying. – mason Mar 02 '17 at 20:25