Unit Testing - jamongx/twitter-clone GitHub Wiki
What is Unit testing
- Unit testing involves the testing of each unit or an individual component of the software application.
- The purpose is to validate that each unit of the software code performs as expected
- Unit testing is done during development (coding phase) of an application by the developers
- Unit may be a an individual function, method, procedure, module and object
- In Java, JUnit framework is used for unit testing Java applications
- Most of the times one component will depend on other component(s), so while implementing unit tests we should mock the dependencies with the desired behaviour using frameworks like Mockito.
- Example: User Management Feature (UserController, UserService, and UserRepository)
Below are the annotations used in unit testing for each layer and their descriptions.
Controller Layer
Spring Boot Test
@WebMvcTest:
- This annotation is specialized for testing Spring MVC controllers. It only loads beans related to the controller layer.
- When using this annotation, beans of other layers such as Service, Repository, etc., are not loaded. Therefore, these beans must be included in the test using mock objects.
@MockBean(JpaMetamodelMappingContext.class):
- This annotation indicates to replace a bean of type JpaMetamodelMappingContext with a mock object.
- It can be used when you want to remove the dependency on the JPA layer for a specific test.
@MockBean:
- Used in conjunction with @WebMvcTest to write tests that send HTTP requests to controllers and verify the responses.
@AutoConfigureMockMvc(addFilters = false):
- This annotation is used for automatically configuring a MockMvc instance in a Spring Boot test environment.
- It provides the necessary settings for testing Spring MVC controllers using MockMvc, especially disabling the automatic addition of filters, such as Spring Security filters, through the addFilters = false option.
- If Spring Security filters are active, authentication and authorization verification logic can affect the test.
Spring Security
@WithMockUser(username = "user1", roles = {"USER"}):
- This annotation is used with Spring Security to set up a mock user's security context during testing.
- It is used to mimic a real security environment in tests where an authenticated user is required.
JUnit
@BeforeEach:
- In a JUnit test class, a method annotated with @BeforeEach automatically executes before each test method is run.
@Test:
- A method annotated with @Test is recognized and executed as a unit test by JUnit.
- These methods are automatically called by the test runner and each constitutes an independent test case.
Service Layer
JUnit
@ExtendWith(MockitoExtension.class):
- Integrates the Mockito framework into the test class, facilitating the creation of mock objects and auto-wiring with Mockito.
- @ExtendWith is one of the methods to integrate custom extensions into the test lifecycle.
Mockito
@Mock:
- Creates an instance of the specified class as a mock object. This mock object does not contain actual logic but instead performs actions defined during the test.
@InjectMocks:
- An instance of a class annotated with @InjectMocks automatically receives the necessary dependencies during the test.
- These dependencies can be mock or spy objects created using Mockito.
JUnit
@BeforeEach
- Same as above
@Test
- Same as above
Repository Layer
Spring Boot Test
@DataJpaTest:
- This annotation is primarily used for testing JPA-related components.
- By default, @DataJpaTest uses an embedded database (e.g., H2) for testing purposes, but you can configure the test environment to use a real database like PostgreSQL.
JUnit
@BeforeEach
- Same as above
@Test
- Same as above