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