Welcome to the slightly chaotic world of Java testing where tools promise nirvana and sometimes deliver mere runnable code. This cheat sheet walks through the popular Java testing frameworks you will actually use in real projects. Keep JUnit for day to day unit tests and add the others where they earn their keep.
Why start with JUnit 5
JUnit 5 is the standard for unit testing in Java and for good reasons. It supports nested tests, parameterized tests, and extensions that let you hook into lifecycles. Mark test methods with @Test and use extensions for setup help and lifecycle control. If you only adopt one tool for unit tests make it JUnit 5.
When TestNG makes sense
TestNG is not trying to be JUnit. It shines when you need flexible configuration and built in parallel execution for larger suites. Use groups, listeners, and data providers when orchestration matters or when tests need fancy ordering and parallel runs.
Mocking and fluent assertions
Mockito handles mocking and stubbing so you can test units without the rest of the world crashing on your desk. Create readable mocks, stub responses, and verify interactions without drowning in boilerplate.
AssertJ gives you fluent assertions that read closer to English and fail with clearer messages. Replace brittle assert statements with chained assertions for better diagnostics and faster bug hunts.
Spring Test and MockMvc for Spring apps
Spring Test helps you load application contexts, run test slices, and exercise Spring wiring. MockMvc is the standard tool for web layer tests when you want to simulate HTTP requests without starting a real server. Use these when dependency injection and Spring features must be exercised in tests.
BDD style with Cucumber
Cucumber brings business readable testing with Gherkin feature files. It is great when non developers need to review acceptance criteria turned into executable tests. Expect more ceremony but also clearer traceability to requirements.
Spock for expressive specifications
Spock uses Groovy to deliver expressive specification style tests that read like sentences. It is excellent for data driven scenarios and behavior driven descriptions that want compact setup and clear where blocks.
WireMock for HTTP isolation
WireMock simulates HTTP services so your integration tests do not depend on flaky remote systems. Use it to stub endpoints, control response behavior, and keep tests stable and fast.
Suggested stacks that do not cause regret
- Core unit tests: JUnit 5 plus Mockito plus AssertJ for readable assertions
- Spring projects: add Spring Test and MockMvc for slice and web layer tests
- Parallel or complex suite rules: consider TestNG for advanced orchestration
- Business readable acceptance tests: use Cucumber with Gherkin feature files
- HTTP dependent integration tests: stub external services with WireMock
- When you want expressive specs and data driven tests: reach for Spock
Quick rules of thumb
- Start with JUnit 5 for unit testing and keep tests small and fast
- Add Mockito for mocking and AssertJ for assertions that help you debug
- Use Spring Test and MockMvc only when Spring features must be involved
- Pick TestNG if you need built in parallel runs and complex grouping
- Choose Cucumber when non technical stakeholders need readable acceptance tests
- Use WireMock to avoid flaky tests that depend on remote HTTP services
Testing is not a religion. Mix and match JUnit, TestNG, Mockito, AssertJ, Spring Test, Cucumber, Spock, and WireMock based on speed, readability, and maintenance cost. Your tests should make bugs obvious and builds predictable. If a tool makes either of those worse toss it out and try the next one.