Software Development; Software Methodologies; Computer Science
Test doubles are pieces of code used to test other software components. Each of the five types of test double simulates functionality in order to test different capabilities, which can be useful during unit testing.
Test doubles are pieces of code used to test components under test (CUTs), or systems under test (SUTs). A test double conforms to the interface (object methods and properties) required by the component being tested, and can help verify the SUT's correct functionality. Test doubles are useful when the other software components needed to test an SUT have not been developed or are otherwise unavailable. Some allow units of code to be tested when using the real components would be too slow for efficient testing. Each type provides different capabilities that can be useful during unit testing.
A dummy object implements an interface needed to test a component. They are used when an object must simply exist to provide the needed test functionality. For example, a unit test might be conducted to determine if a component can create an object or to provide objects that are needed to test code that adds objects to a data structure. Dummies supply the least functionality of the test double types.
A test stub can not only implement the needed interface (allowing it to serve the same functions as a dummy object), but also provide the functionality to supply inputs required by the SUT. For example, if the SUT requires the time of day be provided when a method in the test double is called, a stub could provide a time as requested. Stubs can be used to test for error and exception handling.
A test spy is typically used to record calls to a class that the SUT is using. For example, a test spy would count the number of times the SUT called the method that provides the time of day, unlike a stub, which would provide the time instead.
As the name implies, a fake object mimics the functionality expected of an object by the SUT but implements it differently from the actual object. Fakes are typically used to speed up testing when using the actual functionality would take too much time. For example, data could be stored in local memory to simulate the existence of a database during testing without connecting to a database server.
The last type of test double is the mock object. Unlike the other test doubles, which test the SUT's inputs, a mock tests the SUT's outputs. For example, a mock would be used to ensure that the SUT passes the correct parameters to the method that provides the SUT with the time of day.
Test doubles are a key element in a successful unit testing program. They allow components of a large software system to be tested individually and at any time in the development cycle without affecting those already tested and deployed or consuming valuable resources, such as network bandwidth and database storage. The various types of test doubles allow different testing approaches to be conducted with the least amount of effort spent on developing the test doubles. Test doubles are also well suited for testing applications developed using object-oriented programming (OOP), which is widely used. Unit tests are often automated, too, saving valuable time in writing, debugging, and maintaining code.
Using test doubles requires developers with the knowledge and experience to create the appropriate test doubles and testing procedures. It also demands the financial and other resources needed to implement a robust testing regime. Therefore, it may not be an appropriate approach for small organizations with limited budgets and few IT staff.
Test doubles are useful in many real-world testing situations. They are particularly useful when testing large, complex, modular systems. For example, an international insurance corporation might be testing a customer relationship management application used by the global sales department. A large team of developers are building this large-scale application using an OOP language. The application features a modular design because it needs to be deployed quickly and be responsive to changes in the sales department's requirements. Such an application is an ideal candidate for the use of test doubles.
Test doubles are a key component in a well-designed unit testing methodology. They allow flexible testing of any type of component in an array of real-world development situations. They work well with many development methodologies and programming languages. These include incremental and iterative development, agile development, extreme programming, and OOP languages. As long as these types of methodologies and technologies are used by developers, test doubles will be widely used.
—Maura Valentino, MSLIS
MacLennan, Bruce J. Principles of Programming Languages: Design, Evaluation, and Implementation. 3rd ed., Oxford UP, 1999.
Meszaros, Gerard. xUnit Test Patterns: Refactoring Test Code. Pearson Education, 2009.
Schneider, David I. An Introduction to Programming using Visual Basic. 10th ed., Pearson, 2016.
Scott, Michael L. Programming Language Pragmatics. 4th ed., Morgan Kaufmann Publishers, 2016.
Van Roy, Peter, and Seif Haridi. Concepts, Techniques, and Models of Computer Programming. Massachusetts Institute of Technology, 2004.