Unit Testing ASP.NET User Controls
page 4 of 5
by Brian Mains
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 30142/ 42

Other Testing Capabilities

Through the unit test inheriting from the custom user control, there are some additional capabilities you get from doing so, such as implement the observer pattern. The user control class can setup or change the property values of various inner controls.  For instance, other controls can be exposed through public properties of the user control base class, and the various properties can be set, as shown below.

Listing 3

public abstract class AssignmentUserControlBase
{
  protected abstract DetailsView AssignmentDetailsView
  {
    get;
  }
  protected abstract GridView AssignmentsView
  {
    get;
  }
  protected abstract TextBox SearchTextBox
  {
    get;
  }
 
  protected override void OnInit(EventArgs e)
  {
    this.AssignmentsView.DataKeyNames = new string[]
    {
      "AssignmentID"
    };
    this.AssignmentsDetailsView.Visible = (this.AssignmentsView.SelectedIndex >
      - 1);
    this.SearchTextBox.Enabled = (this.AssignmentsView.SelectedIndex ==  - 1);
  }
}

As another example, I had an application that allowed access to a registration page only at certain times. The application only allowed registrations before Wednesday afternoon.  After that time, registration was shut down and the registration began again on the next day on Thursday, registering users for the following week.

The approach I used was to create a method that returned the current date, and was defined as protected virtually. In all situations in the real application, this method returned DateTime.Now; however, using this approach allowed me to mock the return value by overriding the method in the unit test and returning the value of a local variable. The overridden method in the unit test looks like this:

Listing 3

private DateTime _currentDate = DateTime.Now;
protected overrides DateTime GetCurrentDate()
{
  return _currentDate;
}

The method returns the current date to the OnInit method in the custom user control class, which controls the times when the application is accessible. The following is that method definition.

Listing 4

protected overrides void OnInit(EventArgs e)
{
  DateTime currentDate = this.GetCurrentDate();
  if (currentDate.DayOfWeek == Wednesday)
  {
    if (currentDate.Hour >= 15)
      //Avoid registration page
    else
      //Allow registration, display warning
  }
      //Else allow access to application
}

The following unit test can test this logic thoroughly because it overrides the GetCurrentDate method and returns the local date variable with a predefined value, which tests the various flows through the OnInit method. The following test asserts that all of the appropriate conditions do what they are meant to do. In instances when the current time is passed the fifteenth hour (past 3 PM), the page should redirect. If it is before that, a warning should be displayed; otherwise, general page access is allowed. The following test can test all of that.

Listing 5

[Test]
public void TestInitialLoad()
{
  _currentDate = new DateTime(2007, 7, 11, 9, 0, 0);
  this.OnInit(EventArgs.Empty);
  //assert that the registration is allowed, and a warning is displayed
 
  _currentDate = new DateTime(2007, 7, 11, 16, 0, 0);
  this.OnInit(EventArgs.Empty);
  //assert that the registration is blocked
 
  _currentDate = new DateTime(2007, 7, 12, 7, 0, 0);
  this.OnInit(EventArgs.Empty);
  //assert that the registration is allowed for the next week
}

If a user control dynamically generates the controls within it, it is possible to test that as well.  For instance, assume that a server-side table is dynamically generated on page load, adding certain controls within certain cells to control the layout. The text within those controls may be dynamically generated from data in this situation. Everything in regards to that process can be tested to ensure the table renders correctly. Take the test below. The first part defines the abstract property that must be overridden (which allows the custom user control class to make use of the visual elements in the ASCX user control). Then, the table's structure is validated after it is initialized (initialization is called in the test's setup method).

Listing 6

private Table _layoutTable = new Table();
protected override Table LayoutTable
{
  get
  {
    return _layoutTable;
  }
}
 
[Test]
public void TestTableGeneration()
{
  Assert.AreEqual(3, _layoutTable.Rows.Count);
  Assert.IsInstanceOfType(typeof(Label),
    _layoutTable.Rows[0].Cells[0].Controls[0]);
  Assert.AreEqual("Search Text:", ((Label)
    _layoutTable.Rows[0].Cells[0].Controls[0]).Text);
 
  Assert.AreEqual(2, _layoutTable.Rows[1].Cells[0].ColumnSpan);
  Assert.IsInstanceOfType(typeof(GridView),
    _layoutTable.Rows[1].Cells[0].Controls[0]);
 
  Assert.AreEqual("5 rows found", _layoutTable.Rows[2].Cells[0].Text);
}

This makes it possible to use Test-Driven Development (TDD) to formulate the structure of the user control and to test the layout creation of the user control.


View Entire Article

User Comments

Title: mr   
Name: rob
Date: 2012-03-15 4:55:09 AM
Comment:
would love a complete solution with usercontrol project and test projects for reference.

Product Spotlight
Product Spotlight 





Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-04-26 4:09:29 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search