Logo
PREGNANCY
Windows XP
Windows Vista
Windows 7
Windows Azure
Windows Server
Windows Phone
 
 
Windows 7

Testing Code with Visual Studio 2010 : Approaches to Unit Testing

2/3/2012 11:29:38 AM
Within the past few years, unit testing has taken on a life of its own. You're not cool if you're not doing a unit test. One of the hardest choices when creating unit tests is deciding what to test. When you examine code that you want to test, consider the following issues:
  • Public methods: Public methods are those features of your code that are exposed to the outside world. Pretty much everyone agrees you should unit test your public methods. After all, a public method is sitting there saying, "Call me."

  • Private and protected methods: Private and protected methods in your code do the work of your public methods. As a result, some people believe that testing private and protected methods is wasteful. They believe that unit testing public methods implicitly tests private and protected methods. Plus, testing private and protected methods is harder. By their nature, private and protected methods are, well, private and protected. Unlike public methods, they aren't saying, "Call me." Just the opposite is true, so you need to go out of your way to test them.

  • Interactions with other code: Unless you're writing all your application's features in a single function, chances are high your code needs to interact with other code. The very nature of unit testing, however, is that you want to test only a single unit of code. How can you do that if you have to interact with other code?

Public methods are easily tested because, by definition, you can call a public method from anywhere in your code.

People take all kinds of approaches to solve the problems of testing private methods or code that interacts with other code. One popular approach is to use software that specializes in unit testing, usually called unit testing frameworks.

Two approaches to testing code that interacts with other code are stubs and mocks.

1. Letting stubs do the tough testing

By definition, a unit test is supposed to test only one unit of code. No unit of code lives in isolation, however. Most developers work around this pesky paradox by using code stubs, which act as placeholders for units of code that the unit being tested needs to interact with.

The code stub placeholder is better than interacting with the actual units of code because each unit of code introduces a new set of variables. Instead, you can program the code stub to return a consistent set of values against which the unit can interact. Returning a consistent set of values creates predictability, which makes it easier to create tests that you can repeat.

In reality, developers who use stubs usually go ahead and test the real units of code that interact with the unit they're testing — that is, as long as it's simple to do so. For example, say that you create a Customer object with a public method called GetAddress.GetAddress returns an Address object. The Customer and AddressCustomer object to interact with the Address objects are each units of code that have their own set of unit tests. Many developers will create a test that allows their object even though the test extends beyond the unit they want to test.

When the developer encounters a set of code that is too complicated or messy to interact with a simple unit test, the developer usually creates a stub. The stub returns a set of canned values that the developer expects to get from the code.

For example, say that your Customer object has a method called UpdateAddress.UpdateAddress accepts a new address for a customer and passes that data off to an Address object. The Address object calls a service that validates the address against a valid ZIP code database. You don't want to have to deal with all that when you're testing your Customer object.

Instead of using the Address object, you create a stub that returns two possible values. If you pass a valid address, it returns the value ValidAddress. If you pass an invalid address, it returns the value InvalidAddress. So, how does the stub know what's a valid address and what's an invalid address? You specify in the stub that 123 Main Street, for example, is a valid address. Everything else is invalid. Figure 1 shows an example of a stub.

Figure 1. Use stubs any time you want to avoid messy code interactions in your testing.

2. Simplifying testing with mocking objects

Other developers believe that creating a bunch of objects and stubs is too much work. These developers use a special library to create mock objects. With mock objects — mocks — you tell the object which methods you expect it to run, how many times the methods will run, and what values to return.

For example, say that you use a mock Address object to interact with your Customer address. For your UpdateAddress test, you tell the mock Address object to call the Address object's Save method. Your test tells the mock object that you're going to send a value of 123 Main Street to the Save method and that you expect it to return a value of true. Your test also tells the mock object that you're going to send the value 123 Nowhere Boulevard and that you expect the Save method to return the value false. Figure 2 shows an example of a mock object.

Figure 2. Use mock objects to set expectations about methods called and values returned.

3. Stubs versus mocks

Deciding which method to use can be a little difficult at first glance, but several key differences exist between using mocks and stubs, based on what you want to test for. Here are some of them:

  • Mocks

    • You tell your mock objects which methods to call, how many times they'll be called by your test, and what return values you expect.

    • You create mocks for all objects with which your code interacts.

    • Mocks require a library of code to create the mock objects.

  • Stubs

    • Stubs usually return only values.

    • You create stubs only when necessary.

People who use stubs tend to test clusters of interacting objects together. For example, they might test all the code related to customers and orders together because those units of code interact.

People who use mocks, on the other hand, are more likely to take a top-down approach. They might start testing at the user interface level first and then use mock objects to mimic the behavior of business rules or data access code. They are likely to test first and code second. In other words, they use testing as a way to discover what code they still need to write to make their system work.

NOTE

Using mock objects is very popular in the test-driven development (TDD) style. With TDD, you test first and code second. For more information, see the Test Driven Web site at www.testdriven.com.

4. Automating Tests with Testing Frameworks

Unit tests are often grouped so that they can be executed by a testing framework. A framework isn't necessary, but using a framework allows you to do these things:
  • Formalize unit testing.

  • Create consistency among unit tests.

  • Make automating testing easier.

  • Execute groups of tests at one time.

Frameworks are a necessity for most systems. Because unit tests are so small in nature, even a simple system has lots of tests. In most cases, using a framework to administer the tests makes sense. Unit testing frameworks exist for nearly every programming language under the sun. Popular unit testing frameworks for the .NET Framework include

  • NUnit: By far, NUnit is the most-popular testing framework around. NUnit is an open source (free) framework. However, a drawback to NUnit is that it isn't integrated into Visual Studio. Still, many folks use NUnit to manage their unit tests. You can visit the NUnit Web site at www.nunit.org.

  • NMock: Creates mock objects for use with unit tests.

  • TestDriven.NET: Integrates testing frameworks, such as NUnit, into the Visual Studio development environment. TestDriven.NET gives you the ability to access testing commands from a shortcut menu in the code editor. You can visit the TestDrive.NET Web site at www.testdriven.net.

Other -----------------
- Managing Printers Using Print Management (part 2) - Configuring Printer Driver Isolation Mode
- Managing Printers Using Print Management (part 1) - Configuring Properties of Printers, Publishing Printers in AD DS & Managing Printer Drivers
- Understanding the Print Management Console (part 2) - Configuring Default Security for Print Servers
- Understanding the Print Management Console (part 1) - Enhancements to the Print Management Console in Windows 7
- Managing Printing : How Printing Works in Windows 7
- Taking Advantage of Volume Licensing : KMS and the Client (part 2)
- Taking Advantage of Volume Licensing : KMS and the Client (part 1) - Changing the Client License Type After Installation & Postponing Activation
- Power Searches - AND, OR, and NOT searches, Date and number searches
- Microsoft Access 2010 : Exporting Information (part 2) - Exporting to XML Files
- Microsoft Access 2010 : Exporting Information (part 1)
- Microsoft Project 2010 : Saving a Set of Columns as a Table
- Microsoft Project 2010 : Adding and Removing Columns in a View
- Metadata and Power Searches : Setting Properties When You Save & Personalizing Searches
- Metadata and Power Searches : Working with File Properties
- Tracking Your Licenses with the Key Management Service (part 2) - Configuring DNS to Let KMS Clients Find the KMS Server
- Tracking Your Licenses with the Key Management Service (part 1) - Installing and Initializing KMS
- Taking Advantage of Volume Licensing : Choosing the Right Volume License Key for Windows
- Windows 7 Kernel Mode Drivers Overview and Operations : KMDF I/O Model (part 2)
- Windows 7 Kernel Mode Drivers Overview and Operations : KMDF I/O Model (part 1) - I/O Request Handler
- Windows 7 Kernel Mode Drivers Overview and Operations : KMDF Object Model
 
 
Most view of day
- Microsoft Excel 2010 : Using Formulas - Copying a Formula, Formula Operators
- Windows Server 2012 : Installing and Managing Hyper-V in Full or Server Core Mode - Installing Windows Server 2012 and Microsoft Hyper-V Server 2012
- Integrating SharePoint 2013 with the Office Applications (part 10) - Microsoft Outlook - Lists and Libraries
- Windows Phone 8 : Configuring Basic Device Settings - Passwords and Screen Timeouts (part 2) - Enabling a Password
- Microsoft Excel 2010 : Calculating the Mean (part 1) - Understanding Functions, Arguments, and Results
- Microsoft OneNote 2010 : Doing Research with Side Notes (part 1) - Creating Side Notes
- Participating in Internet Newsgroups : Downloading Messages
- Adobe Dreamweaver CS5 : Working with Multimedia and Online Tools - Checking for Plug-ins
- Editing Digital Video with Windows Live Movie Maker (part 2) - Understanding the Movie Maker User Interface
- Participating in Internet Newsgroups : Setting News Options - Options for Newsgroups and Messages, Options for Individual Newsgroups
Top 10
- Windows Phone 8 : Configuring Mailbox Settings (part 5) - Configuring Automatic Replies
- Windows Phone 8 : Configuring Mailbox Settings (part 4) - Lightening the Display,Changing the Mailbox Sync Settings
- Windows Phone 8 : Configuring Mailbox Settings (part 3) - Message Signatures, Blind CCing Yourself
- Windows Phone 8 : Configuring Mailbox Settings (part 2) - Unlinking Mailboxes, Conversation View
- Windows Phone 8 : Configuring Mailbox Settings (part 1) - Linking Mailboxes
- Managing Windows Server 2012 Systems : Configuring Roles, Role Services, and Features (part 6) - Tracking installed roles, role services, and features
- Managing Windows Server 2012 Systems : Configuring Roles, Role Services, and Features (part 5) - Installing components at the prompt
- Managing Windows Server 2012 Systems : Configuring Roles, Role Services, and Features (part 4) - Managing server binaries
- Managing Windows Server 2012 Systems : Configuring Roles, Role Services, and Features (part 3) - Adding server roles and features
- Managing Windows Server 2012 Systems : Configuring Roles, Role Services, and Features (part 2) - Installing components with Server Manager - Viewing configured roles and role services
 
 
Windows XP
Windows Vista
Windows 7
Windows Azure
Windows Server
Windows Phone
2015 Camaro