« ASP.NET Unit Testing issue on IIS with VS 2008 | Main | Debugging ASP.NET Unit Tests with VS 2008 »

ASP.NET Unit Testing on IIS

In my previous blog I had mentioned about the issue in generating private accessors for ASP.NET code that is hosted on IIS. Does this mean that we can't test the web site if hosted on IIS?

You can, but it will be a bit more complex and you may not be able to cover all scenarios. The idea is to work with the PrivateObject that is available from the test context. In the previous blog, I had talked about a web site with a Calculator class in the App_Code folder that i wanted to test. Let's continue with the same example.

In order to run the application, I had a page that had two text boxes from which I would enter the input values and it had four buttons, one each for invoking Add, Subtract, Multiply and Divide functionality and finally another text box that would capture the results.

Before being able to invoke the buttons, I had to ensure that the text boxes had appropriate values set. For this I used the MyTestInitialize routine so that the values will be set before each test is executed. The initialization I did was as follows

        //Use TestInitialize to run code before running each test

        [TestInitialize()]

        public void MyTestInitialize()

        {

            x = 20;

            y = 5;

 

            Page page = testContextInstance.RequestedPage;

            TextBox t1 = (TextBox)page.FindControl("TextBox1");

            t1.Text = x.ToString();

            TextBox t2 = (TextBox)page.FindControl("TextBox2");

            t2.Text = y.ToString();

        }

The test context allows access to the current page which can be set via the UrlToTest attribute set on each test method. Using this page object, I accessed the two text boxes and initialized them. Then came the actual test method and it looked something like below

        /// <summary>

        ///A test for Subtract

        ///</summary>

        [TestMethod()]

        [HostType("ASP.NET")]

        [UrlToTest("http://localhost/GenericWebApp")]

        public void SubtractTest()

        {

            Page page = testContextInstance.RequestedPage;

            Button b = (Button)page.FindControl("btnSubtract");

 

            PrivateObject po = new PrivateObject(page);

            po.Invoke("btnSubtract_Click", b, EventArgs.Empty);

 

            TextBox t = (TextBox)page.FindControl("TextBox3");

            int actual = Convert.ToInt32(t.Text);

            int result = 15;

            Assert.AreEqual<int>(result, actual);

        }

Few things to note in the above method

1. I used the PrivateObject to invoke the Subtract button's event handler in the page's code behind code.
2. The second parameter to the Invoke method could have been set as null also. If you are making use of the sender parameter in the button click event handler, then you need to send it, else you can very well just sent a null.
3. I used the generics overload of the Assert method to ensure that I can pass int to save on a bit of performance overhead of otherwise boxing and unboxing.

In a similar way, I can test all the other methods of my Calculator class. Needless to say this is a pretty simple scenario and hence invoking methods via the RequestPage object is easy. As the logic becomes complex, the effort to write the test method will increase as you may have to access multiple controls on the page and initialize them appropriately.

Comments are always welcome !

 

Comments

Is FindControl a method you created? If so could you post it? I am trying to do unit testing for a class I am in and am having problems accessing the the controls like textboxs, buttons, and gridview.

Jason, FindControl is a method exposed by Page class. See more details here - http://msdn.microsoft.com/en-us/library/system.web.ui.page.findcontrol.aspx

To run the test cases on the IIS, do i need to decorate the test methods with the attributes
HostType,UrlToTest,AspNetDevelopmentServerHost

how to host the test cases on IIS? is there any way to do that? any useful links...

Nimesh, usually you don't have to worry about the attributes since the test generation wizard will take care of these. Check out articles on MSDN on these like http://msdn.microsoft.com/en-us/library/ms364077(VS.80).aspx.

You can also check the quick reference buide on this - http://vstt2008qrg.codeplex.com/

If there was a function with return type List inside in the class that is under App_Code folder, how can we call that function in the test?

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

Please key in the two words you see in the box to validate your identity as an authentic user and reduce spam.

Subscribe to this blog's feed

Follow us on

Blogger Profiles

Infosys on Twitter