views:

903

answers:

3

I have created a new solution with a minimal amount of code that represents the issue I am having. This is the simplest I could get it down to.

namespace EntServ.BusinessObjects
{
    /// <summary>
    /// Summary description for EntServSession
    /// </summary>
    public class EntServSession
    {
        public EntServSession()
        {

        }

        public static EntServSession Login(string username, string password)
        {
            EntServSession ret = null;

            if (username == "test"  && password == "pass")
                ret = new EntServSession();

            return ret;
        }

    }
}

I started with a new solution, and created one class in the App_Code folder with one static method similar to one of the methods I was having an issue with. I right-clicked on the classname, and click "Create Unit Tests...". It offered to create a new Test project for me, I accepted the defaults and clicked okay. It generated the following file:

using EntServ.BusinessObjects;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.TestTools.UnitTesting.Web;
using System.Data;

namespace EntServObjectTests
{


    /// <summary>
    ///This is a test class for EntServSessionTest and is intended
    ///to contain all EntServSessionTest Unit Tests
    ///</summary>
    [TestClass()]
    public class EntServSessionTest
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion


        /// <summary>
        ///A test for Login
        ///</summary>
        // TODO: Ensure that the UrlToTest attribute specifies a URL to an ASP.NET page (for example,
        // http://.../Default.aspx). This is necessary for the unit test to be executed on the web server,
        // whether you are testing a page, web service, or a WCF service.
        [TestMethod()]
        [HostType("ASP.NET")]
        [AspNetDevelopmentServerHost("%PathToWebRoot%\\EntServ2-ASP.NET\\trunk\\WWW", "/WWW")]
        [UrlToTest("http://localhost/WWW")]
        public void LoginTest()
        {
            string username = string.Empty; // TODO: Initialize to an appropriate value
            string password = string.Empty; // TODO: Initialize to an appropriate value
            EntServSession expected = null;
            EntServSession actual = EntServSession_Accessor.Login(username, password);
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("Verify the correctness of this test method.");
        }

    }
}

I tried running the test and it tries to compile and I get the build error:

Error   1 
The type or namespace name 'EntServSession' could not be found 
(are you missing a using directive or an assembly reference?)   C:\Projects\EntServ-ASP.NET\trunk\Tests\EntServObjectTests\EntServSessionTest.cs
82
13
EntServObjectTests

I publish the web site and put a reference to the App_code.dll in the test project and I no longer get a build error. I instead get the following exception error. I put break points on every line of the class, and the debugger does not stop on any line .

Error Message
Test method EntServObjectTests.EntServSessionTest.LoginTest threw exception:  System.InvalidCastException: Unable to cast object of type 'EntServ2.BusinessObjects.EntServSession' to type 'EntServ2.BusinessObjects.EntServSession'..

Stack Trace
EntServ2.BusinessObjects.EntServSession_Accessor.Login(String username, String password)
EntServObjectTests.EntServSessionTest.LoginTest() in C:\Projects\EntServ2-ASP.NET\trunk\Tests\EntServObjectTests\EntServSessionTest.cs: line 83
+1  A: 

Re-edit:

I can't really solve your exact problem the InvalidCastException as this is probably one of those red-herring / rabbit holes problems that take you days to figure out and much hair pulling out. I am sure it will have something to do with assembly versions being different when you are publishing them??

I don't usually do this and you can vote me down for bad advice, but can I recommend that you convert your asp.net website to a web application? (either this or move the offending code to a class library). I know that this is not the answer you are looking for, but it's tough love what can I say. You will find in the long run it will be far easier and I won't go into all the benefits as I'm sure you will have heard of them or can google them.

I am sure that this will be a much quicker solution to your problem... and after all who really wants to publish their site each time they run their unit-tests?

Xian
can't use the debugger, it throws the exception before ever hitting a breakpoint. The test project is setup in a different folder under a separate project, within the same solution and test code is not deployed with site. there is no assemblyinfo.cs for web apps.
stephenbayer
Ok my mistake, it wasn't clear to me that you were using a asp.net web site project and not a web application, I also misread EntProject for EnterpriseLibrary (long day :). So it is throwing an exception before even hitting the first line of the test?
Xian
that is correct.. I have made a new solution simplified down to 4 files, that still has this problem. EntServ is just a namespace I'm temporarily using in my test.. I'm about to post the minimalist amount of code that still has the issue.
stephenbayer
I have re-edited my answer as I honestly think it is the answer I need to give.. like I say not what you are really looking for unfortunately, but I think what you are seeing is a symptom of something else.
Xian
You know.. publishing it as a class library is not a bad idea, except when I get to unit testing the ascxes and asmxes, that won't work out so well. I'll try this tonight. thanks for your assistance, even thought I'm still perplexed at this issue.
stephenbayer
A: 

It does not appear to me that this class has anything to do with ASP.NET or that it requires any server hosts or deployment mocking at all. You have these lines:

[TestMethod()]
[HostType("ASP.NET")]
[AspNetDevelopmentServerHost("%PathToWebRoot%\\EntServ2-ASP.NET\\trunk\\WWW", "/WWW")]
[UrlToTest("http://localhost/WWW")]
public void LoginTest()
{
    string username = string.Empty; // TODO: Initialize to an appropriate value
    string password = string.Empty; // TODO: Initialize to an appropriate value
    EntServSession expected = null;
    EntServSession actual = EntServSession_Accessor.Login(username, password);
    Assert.AreEqual(expected, actual);
    Assert.Inconclusive("Verify the correctness of this test method.");
}

Try removing the unnecessary components so it reads like this:

[TestMethod()]
public void LoginTest()
{
    string username = string.Empty; // TODO: Initialize to an appropriate value
    string password = string.Empty; // TODO: Initialize to an appropriate value
    EntServSession expected = null;
    EntServSession actual = EntServSession_Accessor.Login(username, password);
    Assert.AreEqual(expected, actual);
    Assert.Inconclusive("Verify the correctness of this test method.");
}

Also, you're not using the test context at all, it might be an idea to remove them for now. I.E. you can remove these:

private TestContext testContextInstance;

/// <summary>
///Gets or sets the test context which provides
///information about and functionality for the current test run.
///</summary>
public TestContext TestContext
{
    get
    {
        return testContextInstance;
    }
    set
    {
        testContextInstance = value;
    }
}

This may not fix your problem, but at least it removes the unnecessary code and could simplify it. If this does not work, can you breakpoint any line of your test after making the change?

Also, you may try initialising your string variables just in case the problem is in the breakpoints and not the test itself.

Finally, why are you testing with the Accessor? Your test code doesn't appear to require access to any private members, so why not juse use an instance of the class itself?

Odd
right clicked on class, clicked on "create unit test" Visual Studio auto generated the code. and test project.
stephenbayer
Yup, it puts in a whole pile of extra stuff just in case you need it. I usually remove everything I don't need from it to save overhead.
Odd
A: 

Debugger is not working with ASP.Net tests.

Use System.Diagnostics.Debugger.Break as a work around