Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Isolating Dependencies in Tests Using Mocks and Stubs

Unit tests are not "unit" tests if they test things other than the System Under Test (SUT).


advertisement

o test a class, a developer must make sure that the class's dependencies won't interfere with its unit tests. Enter mocks and stubs.

Unit tests check on the behavior of units. Think of a class as being a unit. Classes, more often than not, have external dependencies. Tests for such classes should not use their real dependencies because if the dependencies have defects, the tests fail, even though the code inside the class may be perfectly fine.

Suppose you aren't feeling well and go to the doctor to find out what's wrong. The doctor looks at you and quickly says, "You have a problem." How helpful would that be? Without knowing what kind of problem, it's impossible for you to treat it, or to know whether it's a serious problem, or whether it's something that will go away in a day or two.



Instead, the doctor should ask you a couple of questions, analyze the symptoms, decide on a series of exams appropriate to your condition, isolate the variables to diagnose more accurately what's wrong with you, and finally, prescribe the best treatment. After the treatment is complete, the doctor must conduct a few more tests to make sure everything's all right.

Properly written unit tests isolate the system under test from its dependencies, facilitating the identification of defective areas of an application.

Can you draw the parallel with software development here? How many times have users come to you to say, "Your application doesn't work"? That sentence alone doesn't give you enough information to prescribe any cure for your software. You have to run the application through a series of exams so you can pinpoint where the problem is, apply a fix—and then run exams again to ensure you fixed the problem. The exams themselves must be isolated from one another (they mustn't interfere with each other).

This article explores how to isolate a class being tested, also called system under test (SUT from here on), by using fake objects. You'll see how to create static fake objects, as well as how to use dynamic fake objects created by an isolation framework (also called a mock framework).

The Scenario

This article uses a simple Windows Foundation Presentation (WPF) application as the basis for all samples. Figure 1 shows the main (and only) screen for this application.

 
Figure 1. Main Screen: Here's the main screen of the WPF sample application used in this article.

The sample application keeps a list of videos. Each video has a title and a type (BluRay, DVD, or VHS). A user clicks the "Get Movies" button (see Figure 1) to retrieve the list, which can be filtered by video type. The user can then click any video in the list, causing the application to display the details for the movie at the bottom of the screen.

Granted, this is an overly simplistic application, but that's good, because it lets you concentrate on what you are ultimately trying to learn here, which is mocks and stubs.

One particular aspect of this application is that it's implemented based on the Model-View-PresentationModel (MVP) design pattern (or Model-View-ViewModel, which is pretty much the same thing).

This pattern promotes better separation of concerns, by keeping the part that the user sees (the "view") as thin as possible; meaning that it should have as little code as possible. The main logic behind a view goes into a separate object: the "presentation model." The presentation model object interacts with a "model" object, which provides the main data exposed by the view.

The follow is the code behind the main view for the application; the VideosListView class, which inherits from the Window class and implements IVideosListView:

public partial class VideosListView : Window, IVideosListView
{
   public IVideosListPresentationModel Model
   {
      get 
      { 
         return this.DataContext as IVideosListPresentationModel; 
      }
      set { this.DataContext = value; }
   }
   private void listView_SelectionChanged(object sender,   
      SelectionChangedEventArgs e)
   {
      ShowVideoDetailsRequested(this, 
         new OpenVideoRequestedEventArgs(
         listView.SelectedItem as Video));
   }
   private void getVideosButton_Click(object sender, 
      RoutedEventArgs e)
   {
      var selectedType = videoTypeComboBox.SelectedItem.ToString();
      VideoListRequested(this, 
         new VideoListRequestedEventArgs(selectedType));
   }
   public event EventHandler<ShowVideoDetailsRequestedEventArgs>   
      ShowVideoDetailsRequested = delegate { };
   public event EventHandler<VideoListRequestedEventArgs>   
      VideoListRequested = delegate { };
}

You'll notice there isn't much to it. The class exposes a Model property of type IVideosListPresentationModel; as the name suggests, that's the presentation model for this view (the view binds its UI controls to properties on this presentation model).

Other than that, the view simply raises a few events when important things happen, but doesn't know or care what to do beyond raising the events (that's not part of its responsibilities). The events it raises are ShowVideoDetailsRequested (whenever the user selects a video from the list), and VideoListRequested (whenever the user requests the list of videos by clicking on "Get Videos"). All those members are defined in the IVideosListView interface.

Make sure to download the sample code for the application. This article shows only those pieces of code relevant to the point being explained.

Your main task in this article is to write unit tests for the VideosListPresentationModel class, which is the SUT.

Editor's Note: This article was first published in the May/June, 2009 issue of CoDe Magazine, and is reprinted here by permission.



Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap
Thanks for your registration, follow us on our social networks to keep up-to-date