Web site Unit Test: Object reference not set ... error

I tried to setup unit testing for an existing web site by:
1. Create a new websit by pointing to an existing site.
2. Create a new test project
3. Create a new UnitTestLogon.cs page (code attached below)
4. Inside the test manager and run UnitTestLogon.cs
The test can be executed but get Object Reference not set to an object error when loginBox.Text = "UserName"; being hitted.
Any help will be appreciated. Thanks.

using
System;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.VisualStudio.QualityTools.UnitTesting.Framework;
using Microsoft.VisualStudio.QualityTools.UnitTesting.Web;
using System.IO;
using System.Collections;

[TestClass]
public class UnitTestLogon
{
private TestContext testContextInstance;
public TestContext TestContext
{
get { return testContextInstance; }
set { testContextInstance = value; }
}

[TestMethod]
[HostType("ASP.NET")]
[UrlToTest(http://localhost/Test/)]
[WebServerType(WebServerType.WebDev)]
[WebApplicationRoot("/Test")]
[PathToWeb(@"C:\VisualStudio2005Beta2Projects\Test")]

//Alternative, the above cany be set up in Test.testrunconfig

public void UnitTestMethodLogon()
{
Label lblLogin = (Label)page.FindControl("lblUserName");
TextBox loginBox = (TextBox)page.FindControl("txtUserName");
TextBox passBox = (TextBox)page.FindControl("txtPassword");
Button loginButton = (Button)page.FindControl("cmdLogon");

loginBox.Text = "UserName";

//passBox.Text = "Password";
//PrivateObject po = new PrivateObject(page);
//po.Invoke("cmdLogon_Click", loginButton, EventArgs.Empty);
//Assert.AreEqual("Invalid login.", errorLabel.Text);
}
}



Answer this question

Web site Unit Test: Object reference not set ... error

  • porters

    Yes. the button is there.
    Inside the .aspx page, the tag is there:
    <
    asp:Button ID="cmdLogon" Runat="server" CssClass="button"></asp:Button>


  • Lorenzo Colautti

    Okay, I think I've figured this out. To find controls, I had to do this:



    Page page = testContextInstance.RequestedPage;

    MasterPage master = page.Master;

    HtmlForm form = (HtmlForm)master.FindControl("form1");

    ContentPlaceHolder placeHolder = (ContentPlaceHolder)form.FindControl("ContentPlaceHolder1");

    Label lblLogin = (Label)placeHolder.FindControl("lblUserNm");
    ...

     



    So I had to first get the MasterPage, then the form within it, then the ContentPlaceHolder within it. The controls are found within that, so they aren't accessible from the top level of the page. I'll admit I'm not very familiar with the use of master pages, so I'm not sure if there's a more elegant way to do this, but this way worked for me.


  • SuperJoH

    Are you sure you have a Button control name "cmdLogon" on the page

  • jacksparo

    <asp:Button ID="cmdLogon" Runat="server" CssClass="button"></asp:Button>

    It looks like the cmdLogon button does not have an onClick handler. Double-click the button in the designer and one should be added for you.

    asp:Button ID="cmdLogon" Runat="server" CssClass="button" OnClick="cmdLogon_Click">

    Once you have that, this should work out just fine for you.  Let us know please!

    Thank you,

    Michael Brisset

    Visual Studio Team System

     


  • fxcoper

    One more thing: How can I activate the cmdLogon_click inside logon.aspx
  • JBeyer

    Using PrivateObject like you have above should work:


    PrivateObject po = new PrivateObject(page);
    po.Invoke("cmdLogon_Click", loginButton, EventArgs.Empty);

     


    This should be the same as if cmdLogon_Click() were called directly. Is this not working

  • marben79

    Thanks for the reply.
    I look into the page again and found that Master Page being used, below is the code listing of the page. Seems that the only control I can find is: MainMaster.master

    <%@ Page Language="C#" MasterPageFile="~/MainMaster.master" AutoEventWireup="true" CodeFile="Logon.aspx.cs" Inherits="Test.UI.Logon" Title="Logon"%>
    <%
    @ MasterType VirtualPath="~/MainMaster.master" %>
    <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
    <asp:Label id="lblUserNm" runat="server" CssClass="requiredLabel"></asp:Label>
    <asp:TextBox id="txtUserNm" runat="server" CssClass="textBox"></asp:TextBox>
    <br>
    <asp:Label id="lblPassword" runat="server" CssClass="requiredLabel"></asp:Label>
    <asp:TextBox id="txtPassword" runat="server" CssClass="textBox" TextMode="Password"></asp:TextBox>
    <br>
    <span class="spacer"></span>
    <asp:Button ID="cmdLogon" Runat="server" CssClass="button"></asp:Button>
    </asp:Content>

     

  • JPurd

    The "In Progress" status is a known issue. Unfortunately, the behavior in the final release will be to give an error in this case, instead of staying in progress. Since the test is running in the context of Logon.aspx, it can't continue when execution transfers to Default.aspx. For situations where you need a test to span multiple pages, you may want to try web tests--they don't offer the same level of access to objects in the page, but they are designed to include multiple requests and responses across different pages.

    As for why the page was functional without the modification, I'm not sure--on my setup, I needed to both add the OnClick attribute and make the method at least protected to make it work from the browser. The method couldn't be private because the page object at runtime is actually a dynamically generated type that inherits from the class defined in the code file. However, there are several different ways to define ASP.NET pages, so you may have something that works differently than my setup.


  • Rustum

    Thanks. After I added OnClick="cmdLogon_Click" into the Tag and modified private void cmdLogon_Click(... to public void cmdLogon_Click(, the cmdLogon_Click object can be found. Will you please explain why the logon.aspx page is functional without the modification.

    Also, after I execute the test page, the status for this page is always in "In Progress" in side the Test Result window. Below is the code for cmdLogon_Click:

    public void cmdLogon_Click(object sender, System.EventArgs e)
    {
    Response.Redirect(
    "Default.aspx");
    }


  • Rob Clapham

    I'm not sure why this is--my page will compile with it either public or protected, regardless of the AutoEventWireup setting. I'm afraid this is going beyond my knowledge of the intricacies of ASP.NET, so you may want to try the ASP.NET 2.0 forum for better help. You can ask further questions about ASP.NET testing here, but when it comes to issues of compiling the page, they may have better answers there.
  • sskalskii

    Getting the following error with the above code:

    Failed MethodUnitTestLogon Project 
    Test method Project.UnitTestLogon.MethodUnitTestLogon threw exception: 
    System.MissingMethodException: Method 'ASP.Logon_aspx.cmdLogon_Click' not found..

  • DirkR

    If compile after adding OnClick="cmdLogon_Click" into the Tag  with "public void cmdLogon_Click...", the following error will be generated:
    'Project.UI.Logon.cmdLogon_Click(object, System.EventArgs)' is inaccessible due to its protection level C:\...\Project\Logon.aspx
    It will compile if public void cmdLogon_Click... being changed to protected void cmdLogon_Click...

    I have AutoEventWireup="true" inside the Logon.aspx page. Will it be the cause of the issue

  • Werner Sandner

    I tried creating a basic page with those controls and was able to successfully run the test. In your case it looks like loginBox is null, meaning that page.FindControl("txtUserName") probably couldn't find the control (though you may want to use some Console.WriteLine()s or Assert.IsNotNull()s to see exactly what's going on).

    Is the page you're testing called default.aspx If it isn't the default page, you'll need to adjust the UrlToTest so it specifies the exact page, e.g. [UrlToTest("http://localhost/Test/Login.aspx")]. Also, if you dynamically create any controls, they may not be available to the test. Tests run before Page_Load is called for the page, so any changes that would happen then won't be reflected when tests run. I can't say for sure what the problem is for this test, but see if any of this helps with it.

  • Marcel Kunz

    Thanks. After I added OnClick="cmdLogon_Click" into the Tag and modified private void cmdLogon_Click(... to public void cmdLogon_Click...

    >> The method shouldn't need to be public.  Does the test work if cmdLogon is private (with the onClick handler)

    thanks!

    ~ Michael

  • Web site Unit Test: Object reference not set ... error