JDBDT assertions allow you to verify the contents of a database:
δ-assertions state the expected incremental changes made to the database, i.e., an expected database delta. The figure below illustrates the mechanism. Starting from state S, called the reference snapshot, the SUT (software under test) acts on the database, yielding a new database state, S’. S and S’ will have in common unchanged data U = S ∩ S’, but will differ by δ = (O, N), where O = S − S’ is the old data in S no longer defined in S’, and N = S’ − S is the new data in S’.
The programming pattern in line with this scheme is as follows:
Define reference snapshot(s) for the data source(s) of interest theSUT.changesTheDB(); Call delta assertion method(s)
A data source snapshot is a data set that is used as reference for subsequent delta assertions. It can be defined in two ways for a data source s:
Illustration
import static org.jdbdt.JDBDT.*; import org.jdbdt.DataSet; import org.jdbdt.Table; import org.jdbdt.DataSource; ... // [1] Populate a table with some data. Table t = ...; DataSet data = data(t). ...; populate(data); // --> 'data' becomes the reference snapshot // [2] OR take a snapshot. DataSource s = ... ; // 's' can be a Table or Query takeSnapshot(s); // --> internally takes and records a snapshot
The elementary δ-assertion method is assertDelta. An assertDelta(oldData, newData) call, where oldData and newData are data sets for the same data source s, checks if the database delta is (oldData,newData), as follows:
A number of other assertion methods are defined for convenience, all of which internally reduce to assertDelta, as follows:
Method | Description | O | N |
---|---|---|---|
assertDelta([msg,] oldData, newData) | Asserts that δ = (oldData,newData). | oldData | newData |
assertDeleted([msg,] data) | Asserts that data was deleted. | data | ∅ |
assertInserted([msg, ] data) | Asserts that data was inserted. | ∅ | data |
assertUnchanged([msg,] source) | Asserts no database changes took place. | ∅ | ∅ |
Illustration
DB db = ... ; Table t = table("USERS") .columns("ID", "LOGIN", "NAME", "PASSWORD", "CREATED") .build(db); ... // Assert that no changes took place. ... define snapshot with populate or takeSnapshot ... letTheSUT_doNoChangesToDB(); assertUnchanged(t); // Assert an insertion ... define snapshot with populate or takeSnapshot ... letTheSUT_insertOneUser( ... ); assertInserted(data(t).row(999, "john", "John Doe", "justDoeIt", Date.valueOf("2016-01-01")); // Assert a removal ... define snapshot with populate or takeSnapshot ... letTheSUT_removeUserById( 999 ); assertDeleted(data(t).row(999, "john", "John Doe", "justDoeIt", Date.valueOf("2016-01-01")); // Assert an update. ... define snapshot with populate or takeSnapshot ... DataSet before = data(t).row(999, "john", "John Doe", "justDoeIt", Date.valueOf("2016-01-01")); DataSet after = data(t).row(999, "john", "John Doe", "dontDoeIt", Date.valueOf("2016-01-01")); letTheSUT_updatePassword(999, "dontDoeIt") assertDelta(before, after);
A state assertion checks that the database contents in full, and is executed by calling assertState. An assertState([msg,] data) call verifies that the data stored in the database for data.getSource() is (exactly) data as follows:
Note that no reference snapshot needs to be set for a state assertion, unlike δ-assertions.
An assertEmpty([msg,], source) call is equivalent to assertState([msg,], empty(source)), i.e., it verifies that the given data source has no defined rows.
Illustration
DB db = ... ; Table t = table("USERS") .columns("ID", "LOGIN", "NAME", "PASSWORD", "CREATED") .build(db); ... // Assert that table is empty. letTheSUTDeleteAllUsers( ... ); assertEmpty(t); // Assert state after insertion DataSet initialData = ...; populate(initialData); ... DataSet expected = DataSet.join(initialData, data(t).row(999, "john", "John Doe", "justDoeIt", Date.valueOf("2016-01-01"))); letTheSUT_insertOneUser( ... ); assertState(expected);
Two given data sets can be verified as equivalent using the assertEquals method. Note that an assertion of this kind will be insensitive to the order of rows in each data set (like all JDBDT delta or state assertions).
For JUnit users: also beware not to confuse assertEquals with JUnit methods that go by the same name. JUnit’s assertEquals will not work properly, since DataSet (deliberately) does not override Object.equals. All will go well if you use a static import for all methods in the JDBDT facade.
Illustration
// Fill a database table. DB db = ... ; Table t = table("USERS") .columns("ID", "LOGIN", "NAME", "PASSWORD", "CREATED") .build(db); DataSet initialData = ...; populate(initialData); ... // Assert that all data is returned. DataSet expected = initialData; List<User> listOfUsers = letTheSUTQueryAllUsers( ... ); Conversion<User> conv = ...; DataSet actual = data(t, conv).rows(listOfUsers); assertEquals(expected, actual);
The assertTableExists assertion methods verifies if a given table exists in the database. Symmetrically, assertTableDoesNotExist verifies that a table does not exist (e.g., has been dropped by the SUT).
Illustration
DB db = ...; letSUTDoSomething(); assertTableExists(db, "USERS") assertTableDoesNotExist(db, "TEMP_USERS")