The Community Blog is a personal opinion of community members and by no means the official standpoint of DNN Corp or DNN Platform. This is a place to express personal thoughts about DNNPlatform, the community and its ecosystem. Do you have useful information that you would like to share with the DNN Community in a featured article or blog? If so, please contact [email protected].

Creating Testable Modules - Hello World

At Open Force Europe, this fall, I will be presenting a talk on Creating Testable Modules. This is part 3 of a series of blogs where I intent to describe the process as I work my way through developing this talk. In previous posts, I have introduced some of the concepts including the Model View presenter design pattern. In this blog I will dig deeper into this pattern by creating a simple Hello World application. I will be using the Passive View variant of the pattern (see Figure 1).

Figure 1 – MVP – Passive View

As can be seen from the diagram, while everything is centered on the Presenter, it is the View that receives the initial request, and it is the View that is instantiated by the WebForms Framework.

Hello World Requirements

Our “Hello World” application is actually a little more than the typical Hello World application. It has the following requirements.

The application will include a label, a text box to enter text and two buttons – Submit and Reset.

On initially browsing to the page the label will give the user instructions

When the user clicks the Submit button, the label is updated to display “Hello “ and the text the user enters in the text box

When the user clicks the Reset button, the label is reset to display the initial instructions.

These are pretty straightforward requirements, but they should allow us to see how the MVP pattern works.

Figure 2 – The Hello World MVP Web Application Project

You will note that I have followed the convention used in ASP.NET MVC, by creating separate folders for the Models, Presenters and Views. This is not required, but is just a convenience.

This particular example is not a DotNetNuke module as it is just designed to demonstrate the basic pattern.

You will also note that there is an interface for both the View (IView) and the Model (IModel). While you will almost always see interfaces defined for the View, you will not always see an interface for the Model, but interfaces make the whole system more testable as it allows us to use Mock (fake) versions of the objects when Unit Testing.

The Model

We will start by looking at the Model. Listing 1 shows the IModel Interface. Its pretty basic, one property - Text - to hold the text to display.

Listing 2 – Model Class

In fact, in order to meet our requirements we don’t actually need a Model class as we don’t need to persist the text entered by the user.

The View

We are using the Passive View variant of the MVP pattern, so our View is pretty dumb. Listing 3 shows the IView Interface.

Listing 3 – IView Interface

1: publicinterface IView

2: {

3: string Label { set; }

4: string Text { get; }

5: }

The interface defines the basic elements of the View that the Presenter will need to interact with – ie the Presenter will need to read the Text property and set the Label property. In addition to implementing this simple interface, the actual HelloWorldView concrete class will need to manage the events raised by the Submit and Reset buttons.

Lets first look at the ascx file for the concrete View (Listing 4). The ascx file is fairly straightforward. It has a Label, a TextBox and two Buttons as specified in the requirements.

The two properties, Text and Label, specified in the interface encapsulate the Text properties of the Textbox and Label controls. The control has a private variable of type Presenter, which is instantiated in the control’s constructor, passing itself as a constructor parameter so the Presenter can reference the View’s public properties. The View’s event handlers (submit_Click and reset_Click) and lifecycle methods (OnLoad) call methods on this Presenter instance.

The Presenter

The Presenter is the hub of this pattern, passing information back and forth between the View and the Model. It contains private references to both the View and the Model (defined as being of types IView and IModel). As was seen above, the actual View is passed to the constructor of the Presenter, when it is instantiated in the Constructor of the View. In order to satisfy the initiial requirements the Model variable is also instantiated in the Presenters constructor and its value is set to the introduction text (IntroText).

The OnViewLoaded, Reset and Update methods which are called by the Views lifecycle methods and event handlers, handle all the communication between the Model and the View and vice versa.

As was mentioned above the Model is not really necessary in this simple example – it is just used to store the value of the text entered by the user, and in this scenario, this could be handled by a private variable in the Presenter class itself.

This was a simple demonstration of the MVP – Passive View pattern. In the next blog I will develop some tests for it.

Content Layout

Subscribe to DNN Digest

Subscribe to DNN Digest

DNN Digest is our monthly email newsletter. It highlights news and content from around the DNN ecosystem, such as new modules and themes, messages from leadership, blog posts and notable tweets. Keep your finger on the pulse of the ecosystem by subscribing.