Software Testing
Code Coverage
Java
JUnit
JUnit - Extension
-
Resources
JUnit - Parallel Execution
Mockito
-
When shoud you use mock or spy
If you want to be safe and avoid calling external services and just want to test the logic inside of the unit, then use mock.
If you want to call external service and perform calling of real dependency, or simply say, you want to run the program as it is and just stub specific methods, then use spy.
-
Resources
Initialize objects annotated with Mockito annotations
Including @Mock
, @Spy
, @InjectMocks
and @Captor
.
- Use
@ExtendWith(MockitoExtension.class)
to enable Mockito annotations in JUnit 5 tests.
or
-
Programatically
@BeforeAll void beforeAll() { MockitoAnnotations.openMocks(this); }
@Mock
- Use
@Mock
to create a mock object.
@Spy
- Use
@Spy
to create a spy object.
@InjectMocks
- Use
@InjectMocks
to inject mocks (objects annotated with@Mock
) or spies (objects annotated with@Spy
) into the annotated field, but the object itself is not mocked or spied.
Awaitility
Replace Thread.sleep()
Awaitility.await()
.timeout(6, TimeUnit.SECONDS)
.pollDelay(5, TimeUnit.SECONDS)
.untilAsserted(() -> producer.partitionsFor(record.topic()));
Spring Test
Unit Testing
MockMvc
is used to test the controller layer without needing a real HTTP server.@WebMvcTest
is used to test the controller layer with only the controller layer.- Use
@DataJpaTest
to test repositories with an embedded database.
@TestConfiguration
- Use
@TestConfiguration
to provide additional beans for testing. - Create a static nested class in the same test class where we want to autowire the bean.
- Create a separate test configuration class and import it using the
@Import
annotation.
@TestPropertySource
-
Use
@TestPropertySource
to set configuration properties for tests.@TestPropertySource(properties = { "spring.datasource.url=jdbc:h2:mem:test", "spring.datasource.driverClassName=org.h2.Driver", "spring.datasource.username=root", "spring.datasource.password=secret", "spring.flyway.enabled=false" })
Alternatively, use
@SpringBootTest
to set configuration properties for tests.@SpringBootTest(properties = { "spring.datasource.url=jdbc:h2:mem:test", "spring.datasource.driverClassName=org.h2.Driver", "spring.datasource.username=root", "spring.datasource.password=secret", "spring.flyway.enabled=false" })
@DynamicPropertySource
-
Use
@DynamicPropertySource
to set dynamic configuration properties for tests.@DynamicPropertySource static void kafkaProperties(DynamicPropertyRegistry registry) { registry.add("spring.kafka.bootstrap-servers", kafkaContainer::getBootstrapServers); }
-
@DynamicPropertySource
have higher precedence than those loaded from@TestPropertySource
, the operating system'senvironment variables
, Javasystem properties
, or property sources added by the application declaratively by using@PropertySource
or programmatically. Thus, dynamic properties can be used to selectively override properties loaded via@TestPropertySource
,system property sources
, andapplication property sources
.
@DirtiesContext
- Use
@DirtiesContext
to reset the Spring context after a test.
@MockBean
/ @MockitoBean
- Mocked bean in a
Spring ApplicationContext
- Deprecated in favor of
@MockitoBean
sinceSpring Boot 3.4
@SpyBean
/ @MockitoSpyBean
@SpyBean
fromSpring Test
, is used to create a realSpring bean
(if it’s not already defined as a bean) and then spy on it.- An object will behave like an
@Autowired
object. - All its methods will actually work, but we can define some custom behavior for its methods.
- Use
doReturn(...)
/doNothing(...)
to add custom (mocked) method behaviour - Use if you want to provide your mock behaviour but not dismiss entirely its normal behaviour
- Deprecated in favor of
@MockitoSpyBean
sinceSpring Boot 3.4
Integration Testing
@SpringBootTest
is used to test the service layer with a real HTTP server.@DataJpaTest
is used to test the repository layer with an in-memory database.TestRestTemplate
is used to test the controller layer with a real HTTP server, and you can also useRestAssured
to test the controller layer.