Using Factories for Test Fixtures


When writing unit tests, we often want to test the behavior of a module in isolation from the modules it uses. For example, we might have a Payroll application that uses a database (see Figure 29-4). We may wish to test the function of the Payroll module without using the database at all.

Figure 29-4. Payroll uses database


We can accomplish this by using an abstract interface for the database. One implementation of this abstract interface uses the real database. Another implementation is test code written to simulate the behavior of the database and to check that the database calls are being made correctly. Figure 29-5 shows the structure. The PayrollTest module tests the PayrollModule by making calls to it and also implements the Database interface so that it can trap the calls that Payroll makes to the database. This allows PayrollTest to ensure that Payroll is behaving properly. It also allows PayrollTest to simulate many kinds of database failures and problems that are otherwise difficult to create. This is a testing pattern known as SELF-SHUNT, also sometimes known as mocking or spoofing.

Figure 29-5. PayrollTest SELF-SHUNTs database


How does Payroll get the instance of PayrollTest it uses as the Database? Certainly, Payroll isn't going to do the creation of PayrollTest. Just as clearly, Payroll must somehow get a reference to the Database implementation it's going to use.

In some cases, it is perfectly natural for PayrollTest to pass the Database reference to Payroll. In other cases, it may be that PayrollTest must set a global variable to refer to the Database. In still others, Payroll may be fully expecting to create the Database instance. In that last case, we can use a Factory to fool Payroll into creating the test version of the Database by passing an alternative factory to Payroll.

Figure 29-6 shows a possible structure. The Payroll module acquires the factory through a global variableor a static variable in a global classnamed Gdatabase-Factory. The PayrollTest module implements DatabaseFactory and sets a reference to itself into that GdatabaseFactory. When Payroll uses the factory to create a Database, the PayrollTest module traps the call and passes back a reference to itself. Thus, Payroll is convinced that it has created the PayrollDatabase, and yet the PayrollTest module can fully spoof the Payroll module and trap all database calls.

Figure 29-6. Spoofing the factory





Agile Principles, Patterns, and Practices in C#
Agile Principles, Patterns, and Practices in C#
ISBN: 0131857258
EAN: 2147483647
Year: 2006
Pages: 272

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net