ASP.NET单元测试困境(奇怪的异常错误)

时间:2009-01-05 17:52:37

标签: asp.net unit-testing

我创建了一个新解决方案,其中包含的代码量很少,代表了我遇到的问题。这是我能做到的最简单的事情。

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;
        }

    }
}

我开始使用新的解决方案,并在App_Code文件夹中创建了一个类,其中一个静态方法类似于我遇到问题的方法之一。我右键单击了类名,然后单击“创建单元测试...”。它提供了为我创建一个新的测试项目,我接受了默认值并点击了确定。它生成了以下文件:

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.");
        }

    }
}

我尝试运行测试并尝试编译,我得到了构建错误:

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

我发布了该网站并在测试项目中引用了App_code.dll,我不再收到构建错误。我反而得到以下异常错误。我在类的每一行都设置了断点,调试器不会停在任何一行上。

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

3 个答案:

答案 0 :(得分:1)

重新编辑:

我无法真正解决你的确切问题InvalidCastException,因为这可能是那些需要花费数天时间才能弄明白并且拔掉头发的红鲱鱼/兔子洞问题之一。我相信当你发布它们时,它会与汇编版本有所不同吗?

我通常不这样做,你可以投票给我一些不好的建议,但我可以建议你将你的asp.net网站转换为网络应用程序吗? (或者将违规代码移动到类库中)。我知道这不是你要找的答案,但我很难说我能说什么。从长远来看,你会发现它会更容易,我不会全部受益,因为我相信你会听到它们或者可以谷歌它们。

我相信这对您的问题来说是一个更快的解决方案......毕竟谁真的想在每次运行单元测试时发布他们的网站?

答案 1 :(得分:0)

在我看来,这个类与ASP.NET无关,或者根本不需要任何服务器主机或部署模拟。你有以下几行:

[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.");
}

尝试删除不必要的组件,使其如下所示:

[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.");
}

此外,您根本没有使用测试上下文,暂时删除它们可能是个主意。 I.E.你可以删除这些:

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;
    }
}

这可能无法解决您的问题,但至少它会删除不必要的代码并简化它。如果这不起作用,您可以在进行更改后断点测试的任何一行吗?

此外,您可以尝试初始化字符串变量,以防问题出现在断点而不是测试本身。

最后,您为什么要使用Accessor进行测试?您的测试代码似乎不需要访问任何私有成员,那么为什么不使用类本身的实例呢?

答案 2 :(得分:0)

调试器无法使用ASP.Net测试。

使用System.Diagnostics.Debugger.Break作为解决方法