Channels ▼
RSS

Tools

Unit Testing the UI

Source Code Accompanies This Article. Download It Now.


Jordan is responsible for front-end development at Liquidnet, an electronic equities trading venue focusing on buy-side institutions. He can be contacted at jvinarub@liquidnet.com.


By using the Model-View-Presenter pattern, Windows Forms 2.0, and automatic data binding, you can create a framework for unit testing the user interface. The pattern enforces a separation of concerns that keeps the UI thin, focusing only on visualization of data and binding to a presentation model. In this article, I present a basic calculator application that leverages this architecture and demonstrates the ease of unit testing from this framework. (The complete source code for the calculator is available electronically; see "Resource Center," page 5.)

For the purposes of this article, you can view the Model-View-Presenter (MVP) pattern as a means to decouple presentation logic from the actual view itself. The goal should be a simple 1-1 mapping between properties in a presenter class and properties in a view class. For example, for each text box display, there should be a corresponding property in the presenter class. If the output requires advanced calculation or formatting to occur prior to display, the model and presenter classes should take care of the data prior to updating the view. Likewise, simple edits should immediately notify the model and presenter of an update in order to drive a new display. In many cases, as well as our simple example, the model and presenter classes can merge into a heavy model class. Because there is little code required to convert the model into presentable data, the model can handle the dual responsibilities of data storage and presentation logic.

The Calculator Application

Figure 1 illustrates a basic calculator form bound to a calculator presentation model.

[Click image to view at full size]

Figure 1: Calculator form with calculator model.

Each data element for display and edit from the view is described by a property, and each button-click action is represented by a parameterless method in the calculator model. By following the MVP pattern, you ensure that the view is focused on visualizing data as well as posting and receiving updates to and from the model.

Listing One includes the code for two of the calculator model's properties. In the listing, the setter for a property notifies consumers once a change has been committed. The Calculator class implements the INotifyPropertyChanged interface from .NET 2.0 in order to support firing events for property changes. In the case of Operand2, CanDivide is updated once Operand2 is updated, so two events are fired.

public class Calculator : INotifyPropertyChanged
{
    public decimal Operand2
    {
        get { return _operand2; }
        set
        {
            if (value == _operand2)
                return;
            _operand2 = value;
            OnPropertyChanged("Operand2");
            OnPropertyChanged("CanDivide");
        }
    }
    public bool CanDivide
    {
        get { return (this.Operand2 != 0); }
    }
    ...
}
Listing One

For these two model properties, there are analogous properties in the calculator form; see Listing Two. These properties in the view demonstrate the concern of visualizing this state of the model.

 
public partial class CalculatorForm : Form
{    
    public decimal Operand2
    {
        get { return Convert.ToDecimal(_operand2TextBox.Text); }
        set { _operand2TextBox.Text = value.ToString(); }
    }
    public bool CanDivide
    {
        get { return _divideButton.Enabled; }
        set { _divideButton.Enabled = value; }
    }
 ...
}   

Listing Two


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video