“Mocking is cool—until it lies to you.”
If you’ve ever mocked your way through a test only to get blindsided in production, welcome to the club. That’s exactly why I started relying on real integration tests using datasets in Java.
Why not unit tests, why integration tests?
Unit tests are fast and focused but don’t touch the real database, objects, or constraints. Integration tests simulate the real thing — they boot your application context, load real data, and let you test how your code behaves in production-like conditions.
Here’s a stripped-down version of how my test class usually looks:
`@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppTestConfig.class)
@Transactional
public class SampleServiceTest extends BaseWebContextSensitiveTest {
@Before
public void setupDataset() throws Exception {
executeDataSetWithStateManagement("testdata/sample.xml");
}
@Test
public void testSaveSample() throws Exception {
Sample sample = new Sample();
sample.setName("Test Sample");
sample.setStatus("Pending");
sampleService.save(sample);
Sample result = sampleService.fetchById(sample.getId());
assertEquals("Test Sample", result.getName());
}
}
What’s in the Dataset?
The sample.xml The file is a snapshot of database rows. Here's what a minimal DBUnit dataset looks like:
<dataset>
<sample id="1" name="Existing Sample" status="Approved"/>
</dataset>
This gets loaded into the test database before each test. It makes your test repeatable and independent of whatever is in the database.
Common Lessons
Here are a few things I’ve learned the hard way:
Make datasets small. Load only what’s needed.
Assert the DB state. Don’t just trust return values — fetch the record and check it.
Use @Transactional With rollback to avoid polluting your test DB.
Don’t mix unit tests with integration tests. Separate them for clarity and speed.
Do you know what the best part is?
If something breaks, like a foreign key violation or bad insert, it breaks for real. That’s what you want in a test. If all your tests pass, but nothing works in staging, that’s a red flag that your mocks lied to you
If you’re working in a legacy codebase or an enterprise app like OpenELIS, you’ll often run into weird behavior caused by data inconsistencies, cascading updates, or transactional issues. Mocking won’t catch that. Real data will.
** Next up, I’ll be writing about: **
- How to deal with circular foreign keys in datasets
- Testing update and delete scenarios with DBUnit
- Making your test data realistic but minimal
Written by Agaba Derrick, an open-source software engineer passionate about reliable backend systems and breaking things the right way.
Follow me on GitHub
Top comments (0)