
656
Chapter 25 Database Patterns
environment than in the application environment and it is not essential that
all tests be run from a single place. For example, a database or data services
team that is writing stored procedures for use by other teams would fi nd this
approach attractive. Another circumstance in which it would be appropriate
to use In-Database Stored Procedure Tests arises when the procedures are
stored in a different source code repository than the application logic. Using
In-Database Stored Procedure Test allows us to store the tests in the same
repository as the SUT (in this case, the stored procedures).
In-Database Stored Procedure Tests may allow somewhat more thorough
unit testing (and test-driven development) of the stored procedures because we
may have better access to implementation details of the stored procedure from
our tests. Of course, this violation of encapsulation could result in Overspecifi ed
Software (see Fragile Test on page 239). If the client code uses a data access layer,
we must still write unit tests for that software in the application programming
language to ensure that we handle errors correctly (e.g., failure to connect).
Some databases support several programming languages. In such a case,
we can choose to use the more test-friendly programming language for our
tests but write the stored procedures in the more traditional stored-procedure
programming language. For example, Oracle databases support both PLSQL
and Java, so we could use JUnit tests to verify our PLSQL stored procedures.
Likewise, Microsoft’s SQL Server supports C#, so we could use NUnit tests
written in C# to verify the stored procedures written in Transact-SQL.
Variation: Remoted Stored Procedure Test
The purpose of Remoted Stored Procedure Tests is to allow us to write the tests in
the same language as the unit tests for the client application logic. We must access
the stored procedure via a Remote Proxy [GOF] that hides the mechanics of inter-
acting with that procedure. This proxy can be structured as either a Service Facade
[CJ2EEP] or a Command [GOF] (such as Java’s JdbcOdbcCallableStatement).
Remoted Stored Procedure Tests are, in effect, component tests in that they
treat the stored procedure as a “black box” component. Because Remoted Stored
Procedure Tests do not run inside the database, we are more likely to write them
as round-trip tests (calling other stored procedures to set up the fi xture, verify
the outcome, and perform other necessary tasks) unless we have an easy way
to insert or verify data. Some members of the xUnit family have extensions that
are specifi cally intended to facilitate this behavior (e.g., DbUnit for Java and
NDbUnit for .NET languages).
This solution is more appropriate if we want to keep all our tests in a single
programming language. The Remoted Stored Procedure Test pattern makes it
easier to run all the tests every time we check in changes to the application code.
Stored
Procedure
Test