Unit Test Design Patterns
Simulation PatternsData transactions are difficult to test because they often require a preset configuration, an open connection, and/or an online device (to name a few). Mock objects can come to the rescue by simulating the database, web service, user event, connection, and/or hardware with which the code is transacting. Mock objects also have the ability to create failure conditions that are very difficult to reproduce in the real world--a lossy connection, a slow server, a failed network hub, etc. However, to properly use mock objects the code must make use of certain factory patterns to instantiate the correct instance--either the real thing or the simulation. All too often I have seen code that creates a database connection and fires off an SQL statement to a database, all embedded in the presentation or business layer! This kind of code makes it impossible to simulate without all the supporting systems--a preconfigured database, a database server, a connection to the database, etc. Furthermore, testing the result of the data transaction requires another transaction, creating another failure point. As much as possible, a unit test should not in itself be subject to failures outside of the code it is trying to test.
To achieve this construct, a certain amount of foresight and discipline is needed in the coding process. Classes need to be abstracted, objects must be constructed in factories rather than directly instantiated in code, facades and bridges need to be used to support abstraction, and data transactions need to be extracted from the presentation and business layers. These are good programming practices to begin with and result in a more flexible and modular implementation. The flexibility to simulate and test complicated transactions and failure conditions gains a further advantage to the programmer when mock objects are used.
This test simulates the connection and I/O methods of a service. In addition to simulating an existing service, this pattern is useful when developing large applications in which functional pieces are yet to be implemented.
I have only used this pattern in limited applications such as simulating bit errors induced by rain-fade in satellite communications. However, it is important to at least consider where errors are going to be handled in the data stream--are they handled by the transport layer or by higher level code? If you're writing a transport layer, then this is a very relevant test pattern.
In this pattern, the mock object simulates a component failure, such as a network cable, hub, or other device. After a suitable time, the mock object can do a variety of things:
throw an exception return incomplete or completely missing data return a "timeout' errorAgain, this unit test documents that the code under test needs to handle these conditions.
source: Marc Clifton - http://www.codeproject.com/KB/architecture/autp5.aspx