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
@Mockto create a mock object.
@Spy
- Use
@Spyto create a spy object.
@InjectMocks
- Use
@InjectMocksto 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
MockMvcis used to test the controller layer without needing a real HTTP server.@WebMvcTestis used to test the controller layer with only the controller layer.- Use
@DataJpaTestto test repositories with an embedded database.
@TestConfiguration
- Use
@TestConfigurationto 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
@Importannotation.
@TestPropertySource
-
Use
@TestPropertySourceto 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
@SpringBootTestto 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
@DynamicPropertySourceto set dynamic configuration properties for tests.@DynamicPropertySource static void kafkaProperties(DynamicPropertyRegistry registry) { registry.add("spring.kafka.bootstrap-servers", kafkaContainer::getBootstrapServers); } -
@DynamicPropertySourcehave higher precedence than those loaded from@TestPropertySource, the operating system'senvironment variables, Javasystem properties, or property sources added by the application declaratively by using@PropertySourceor programmatically. Thus, dynamic properties can be used to selectively override properties loaded via@TestPropertySource,system property sources, andapplication property sources.
@DirtiesContext
- Use
@DirtiesContextto reset the Spring context after a test.
@MockBean / @MockitoBean
- Mocked bean in a
Spring ApplicationContext - Deprecated in favor of
@MockitoBeansinceSpring Boot 3.4
@SpyBean / @MockitoSpyBean
@SpyBeanfromSpring 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
@Autowiredobject. - 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
@MockitoSpyBeansinceSpring Boot 3.4
Integration Testing
@SpringBootTestis used to test the service layer with a real HTTP server.@DataJpaTestis used to test the repository layer with an in-memory database.TestRestTemplateis used to test the controller layer with a real HTTP server, and you can also useRestAssuredto test the controller layer.