.. _ImplementsOfTestByLayer: Implementation of test by layer -------------------------------------------------------------------------------- .. only:: html .. contents:: Index :local: A list of unit test target classes for each layer, a test method, and a summary thereof are shown below. Note that, the test method and the implementation given in this chapter is only an example, and the actual test method and implementation is to be considered in accordance with the test policy. .. tabularcolumns:: |p{0.15\linewidth}|p{0.25\linewidth}|p{0.60\linewidth}| .. list-table:: :header-rows: 1 :widths: 15 25 60 * - Layer - Test method - Summary * - Infrastructure layer - \ :ref:`ImplementsOfTestByLayerTestingRepositoryWithSpringTest`\ - Standard function of Spring Test is used and a test to access data is performed. * - Infrastructure layer - \ :ref:`ImplementsOfTestByLayerTestingRepositoryWithSpringTestDBUnit`\ - DBUnit and Spring Test DBUnit functions are used and a test to access data is performed. * - Domain layer - \ :ref:`ImplementsOfTestByLayerTestingServiceWithSpringTest`\ - \ ``Service``\ is injected by using Spring Test DI function, is combined with infrastructure layer and \ ``Service``\ test is performed. * - Domain layer - \ :ref:`ImplementsOfTestByLayerTestingServiceWithMockito`\ - Mockito is used to mock dependent classes and \ ``Service``\ test is performed. * - Application layer - \ :ref:`ImplementsOfTestByLayerTestingControllerWithStandaloneSetup`\ - \ ``Controller``\ is injected by using Spring Test DI function, is combined with domain layer and infrastructure layer and \ ``Controller``\ test is performed. * - Application layer - \ :ref:`ImplementsOfTestByLayerTestingControllerWithWebAppContextSetup`\ - MockMvc of Spring Test is used to apply \ ``spring-mvc.xml``\ and \ ``applicationContext.xml``\ created in the operation and \ ``Controller``\ test is performed. * - Application layer - \ :ref:`ImplementsOfTestByLayerTestingControllerWithMockito`\ - Mockito is used to mock dependent classes and \ ``Controller``\ test is performed. * - Application layer - \ :ref:`ImplementsOfTestByLayerUnitTestOfHelper`\ - \ ``Helper``\ test is performed. For details of test method, refer test method of \ ``Service``\. Unit test of infrastructure layer ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This section explains about unit test of \ :ref:`LayerOfInfrastructure`\ of development guidelines. .. figure:: ./images/ImplementsOfTestByLayerLayerOfTestTargetRepository.png :width: 95% In infrastructure layer, the test to access data which uses MyBatis from Repository is performed. For details of how to use MyBatis3, refer \ :ref:`repository-mybatis3-label`\. Since \ ``RepositoryImpl``\ which is auto-generated by MyBatis runs on Spring DI container,actualBean definition and \ ``SpringJUnit4ClassRunner``\ of Spring Test provided by Spring DI function are used in the test. For details of Spring Test, refer \ :ref:`UsageOfLibraryForTestSpringTestOverview`\. Following two methods can be listed as data verification methods after test execution. The method to be used should be determined in accordance with the business requirements given separately. * Fetch database status after test execution by using SELECT statement and verify the same. * Validate by using DBUnit and Spring Test DBUnit. This section explains a case wherein \ ``JdbcTemplate``\ is used as a verification method using SELECT statement. \ ``JdbcTemplate``\ is a core class of Spring JDBC support.In JDBC API, it is necessary to acquire connection from data source, create \ ``PreparedStatement``\, analyze \ ``ResultSet``\ and release the connection, however,when \ ``JdbcTemplate``\ is used, many of these processes are concealed and data access can be performed more easily. .. note:: In \ :ref:`ApplicationLayering`\, \ ``Repository``\ interface is a deliverable of domain layer, however, it is introduced here as a unit test target of infrastructure layer. It is recommended to check on the domain layer as well that the interface with \ ``Service``\ is correct. | .. _ImplementsOfTestByLayerUnitTestOfRepository: Unit test of Repository """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" This section explains implementation method for unit test of \ ``Repository``\ given below. .. tabularcolumns:: |p{0.30\linewidth}|p{0.70\linewidth}| .. list-table:: :header-rows: 1 :widths: 30 70 * - Test method - Description * - \ :ref:`ImplementsOfTestByLayerTestingRepositoryWithSpringTest`\ - Use \ ``JdbcTemplate``\ to verify test results. * - \ :ref:`ImplementsOfTestByLayerTestingRepositoryWithSpringTestDBUnit`\ - Use functions of DBUnit and Spring Test DBUnit to verify test results. Here, explanation is given using the test for following deliverables as an example. Note that, for details of Repository implementation, refer \ :ref:`repository-mybatis3-label`\. * Update process (\ ``updateMemberLogin``\ method) of \ ``Repository``\ interface (\ ``MemberRepository``\) * Mapping file (\ ``MemberRepository.xml``\) Implementation example for test is shown below. * ``MemberRepository.java`` .. code-block:: java public interface MemberRepository { int updateMemberLogin(Member member); } * ``MemberRepository.xml`` .. code-block:: xml UPDATE member_login SET last_password = password, password = #{memberLogin.password} WHERE customer_no = #{membershipNumber} | .. _ImplementsOfTestByLayerTestingRepositoryWithSpringTest: Test which only use Spring Test standard function '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Files to be created for unit test of \ ``Repository``\ which use Spring Test are shown below. Further, for setup method of database, refer \ :ref:`PreparationForTestDataSetupWithSpringTest` \. Also, for setup files used while carrying out unit test by using Spring Test, refer \ :ref:`PreparationForTestMakeSettingFileForSpringTest`\. .. figure:: ./images/ImplementsOfTestByLayerRepositorySpringTestItems.png .. tabularcolumns:: |p{0.35\linewidth}|p{0.65\linewidth}| .. list-table:: :header-rows: 1 :widths: 35 65 * - Names of the files to be created - Explanation * - \ ``MemberRepositoryTest.java``\ - Test class of \ ``MemberRepository.java``\. * - \ ``test-context.xml``\ - Setup files supplementing setup required for carrying out unit test by using Spring Test. * - \ ``setupMemberLogin.sql``\ - SQL file to set data of database used in unit test. .. note:: **Creation units of SQL file to be used in unit test** Here, 1 SQL is created for 1 test method. Actual creation units must be considered appropriately depending on test policy and details. Note that, if SQL file path is omitted in \ ``@Sql``\, SQL files are searched based on specified locations of \ ``@Sql``\. For details, refer \ :ref:`Omitting SQL file path of @Sql`\. | How to create a test class of \ ``Repository``\ while using Spring Test is explained. Setup files used for testing by using data access are shown below. * ``sample-infra.xml`` .. code-block:: xml * ``sample-env.xml`` .. code-block:: xml How to create a test of \ ``Repository``\ which use Spring Test is explained. Here, it is assumed that schema for test has already been created, \ ``MemberLogin``\ table is set by using \ ``@Sql``\ annotation, password of \ ``MemberLogin``\ "ABCDE" is updated to new password "FGHIJ", \ ``MemberLogin``\ table is fetched after update and verified. * ``MemberRepositoryTest.java`` .. code-block:: java import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:META-INF/spring/sample-infra.xml", //(1) "classpath:META-INF/spring/test-context.xml" }) //(1) @Transactional // (2) public class MemberRepositoryTest { @Inject MemberRepository target; // (3) @Inject JdbcTemplate jdbctemplate; // (4) @Test @Sql(scripts = "classpath:META-INF/sql/setupMemberLogin.sql", config = @SqlConfig(encoding = "utf-8")) public void testUpdateMemberLogin() { // (5) // setup test data MemberLogin memberLogin = new MemberLogin(); memberLogin.setPassword("FGHIJ"); Member member = new Member(); member.setMembershipNumber("0000000001"); member.setMemberLogin(memberLogin); // (6) // run the test int updateCounts = target.updateMemberLogin(member); // (7) MemberLogin updateMemberLogin = getMemberLogin("0000000001"); // (8) // assertion assertThat(updateCounts, is(1)); assertThat(updateMemberLogin.getPassword(), is("FGHIJ")); assertThat(updateMemberLogin.getLastPassword(), is("ABCDE")); } private Member getMemberLogin(String customerNo) { MemberLogin memberLogin = (MemberLogin) jdbctemplate.queryForObject( "SELECT * FROM member_login WHERE customer_no=?", new Object[] {customerNo }, new RowMapper() { public MemberLogin mapRow(ResultSet rs, int rowNum) throws SQLException { MemberLogin mapMemberLogin = new MemberLogin(); mapMemberLogin.setPassword(rs.getString( "password")); mapMemberLogin.setLastPassword(rs.getString( "last_password")); mapMemberLogin.setLoginDateTime(rs.getDate( "login_date_time")); mapMemberLogin.setLoginFlg(rs.getBoolean( "login_flg")); return mapMemberLogin; } }); return memberLogin; } .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - Sr. No. - Description * - | (1) - | Read \ ``sample-infra.xml``\ and \ ``test-context.xml``\ which retain applications required for running \ ``MemberRepository``\ class. * - | (2) - | When \ ``@Transactional``\ annotation is assigned, start to end of test execution is considered as one transaction and is rolled back by default after the completion of test. If the annotation is defined at the class level, \ ``@Transactional``\ annotation is enabled for all the test methods. * - | (3) - | Inject \ ``MemberRepository``\ class considered as a test target. * - | (4) - | Inject \ ``JdbcTemplate``\ class. * - | (5) - | Create test data for executing a method for testing. * - | (6) - | Execute the method for testing. * - | (7) - | Fetch information of database after update. By using \ ``org.springframework.jdbc.core.RowMapper``\, \ ``ResultSet``\ fetched from database can be mapped to a specific POJO class. * - | (8) - | Verify update count and update results. .. note:: **A method wherein transaction is not rolled back at the time of testing** When \ ``@Transactional``\ annotation is specified in a test case, it is rolled back after execution of test method by default.When you do not want to roll back for using the test data in subsequent tests, \ ``@Rollback(false)``\ annotation or \ ``@Commit``\ annotation is specified besides \ ``@Transactional``\ annotation and transaction at the time of test can be committed. .. warning:: **Regarding @TransactionConfiguration for Spring Framework 4.2 and subsequent versions** Since Spring Framework 4.2, you can set \ ``@Rollback``\ or \ ``@Commit``\ at the class level. With this, \ ``@TransactionConfiguration``\ has been deprecated. However, in the earlier versions of Spring Framework 4.2, when the rollback is to be performed at the class level, \ ``@TransactionConfiguration(defaultRollback = true)``\ should be set. | .. _ImplementsOfTestByLayerTestingRepositoryWithSpringTestDBUnit: Test which use Spring Test DBUnit '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Implementation method of unit test of \ ``Repository``\ while using DBUnit in data access is explained. Note that, an example wherein an Excel format file (.xlsx) is used in data definition file of DBUnit is explained here. For setup method of data definition file and database, refer \ :ref:`PreparationForTestDataSetupWithDBUnit`\. Further, for using Spring Test DBUnit functions together in DBUnit, it is necessary to register \ ``com.github.springtestdbunit.TransactionDbUnitTestExecutionListener``\ by using \ ``@TestExecutionListeners``\ annotation. For registration method, refer \ :ref:`UsageOfLibraryForTestRegistrationOfTestExecutionListener`\. Files to be created in unit test of \ ``Repository``\ which use DBUnit are shown below. .. figure:: ./images/ImplementsOfTestByLayerRepositoryDbunitItems.png .. tabularcolumns:: |p{0.35\linewidth}|p{0.65\linewidth}| .. list-table:: :header-rows: 1 :widths: 35 65 * - Names of files to be created - Description * - \ ``MemberRepositoryDbunitTest.java``\ - Test class of \ ``MemberRepository.java``\ (while linking with DBUnit) * - \ ``XlsDataSetLoader.java``\ - Implementation class of \ ``DataSetLoader``\ interface supporting Excel format. For implementation method, refer \ :ref:`PreparationForTestDataSetupWithDBUnit`\. * - \ ``expected_testUpdateMemberLogin.xlsx``\ - File for verification of expected results of test * - \ ``setup_MemberLogin.xlsx``\ - File for test data setup * - \ ``test-context.xml``\ - Setup file used while carrying out unit test by using Spring Test. Use the same setup file created by \ :ref:`ImplementsOfTestByLayerTestingRepositoryWithSpringTest`\. .. note:: **Creation unit of Excel file used in unit test** Here, a file for data setup and a file for verifying expected results are respectively created in 1 test method. Test policy and details should be appropriately reviewed for the actual creation unit. | How to create a test class of \ ``Repository``\ while using DBUnit is explained. Here, it is assumed that the schema for test is already created. By using \ ``@DatabaseSetup``\ annotation, \ ``MemberLogin``\ table is set, \ ``MemberLogin``\ password is updated from "ABCDE" to new password "FGHIJ" and verified by using \ ``@ExpectedDatabase``\ annotation. How to create a test method of \ ``Repository``\ by using Spring Test and DBUnit is shown below. * ``MemberRepositoryDbunitTest.java`` .. code-block:: java import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:META-INF/spring/sample-infra.xml", // (1) "classpath:META-INF/spring/test-context.xml" }) // (1) @TestExecutionListeners({ DirtiesContextBeforeModesTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class, TransactionDbUnitTestExecutionListener.class}) @Transactional @DbUnitConfiguration(dataSetLoader = XlsDataSetLoader.class) public class MemberRepositoryDbunitTest { @Inject MemberRepository target; @Test @DatabaseSetup("classpath:META-INF/dbunit/setup_MemberLogin.xlsx") @ExpectedDatabase( // (2) value = "classpath:META-INF/dbunit/expected_testUpdateMemberLogin.xlsx", assertionMode = DatabaseAssertionMode.NON_STRICT_UNORDERED) public void testUpdate() { // setup MemberLogin memberLogin = new MemberLogin(); memberLogin.setPassword("FGHIJ"); Member member = new Member(); member.setMembershipNumber("0000000001"); member.setMemberLogin(memberLogin); // run the test int updateCounts = target.updateMemberLogin(member); // assertion assertThat(updateCounts, is(1)); } } .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - Sr. No. - Description * - | (1) - | Read setup file (\ ``sample-infra.xml``\ retained by application and \ ``test-context.xml``\ supplementing it) required for running \ ``MemberRepository``\ class. * - | (2) - | After test method execution, DBUnit automatically compares and verifies the table and expected result data file, by specifying file for verifying expected test results in \ ``@ExpectedDatabase``\ annotation. | Similar to \ ``@DatabaseSetup``\ annotation, it can be assigned at class level and method level. | The file format is same as the test setup data file. Following values can be set in \ ``assertionMode``\ attribute. * \ ``DEFAULT``\ (or not specified): Compare all the tables and columns. * \ ``NON_STRICT``\: If a table or column that does not exist in the expected result data file exists in the actual database, it is ignored. * \ ``NON_STRICT_UNORDERED``\: Further to \ ``NON_STRICT``\ mode, sequence of lines is also ignored. .. warning:: **Table with external key constraints** When database is initialized by using DBUnit for the table with external key constraint, it must be noted that sequence of dataset must be specified in order to maintain data integrity since an error occurs depending on the reference conditions. .. note:: **Sequence verification method** Sequence consists of a feature wherein even if a transaction is rolled back, advanced value does not return. Therefore, when a record consisting of columns numbered from a sequence is to be verified by DBUnit, one of the following measures must be employed. * Columns numbered from the sequence are excluded from verification * Execute SQL which explicitly initializes the sequence and initialize it prior to test implementation * Verify sequence value at the time of test execution and validate the verified value as a standard value | Unit test of domain layer ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This section explains about unit test of \ :ref:`LayerOfDomain`\ of development guideline. .. figure:: ./images/ImplementsOfTestByLayerLayerOfTestTargetDomain.png :width: 95% Business logic of \ ``Service``\ and \ ``@Transactional``\ test are carried out in domain layer. When the test is to be performed by injecting \ ``Service``\ and joining infrastructure layers, similar to test implementation method of \ ``Repository``\, test is performed by using Bean definition, and \ ``SpringJUnit4ClassRunner``\ of Spring Test. For details of Spring Test, refer \ :ref:`UsageOfLibraryForTestSpringTestOverview`\. | .. _ImplementsOfTestByLayerUnitTestOfService: Unit test of Service """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" This section explains how to implement a test of \ ``Service``\ as below. .. tabularcolumns:: |p{0.30\linewidth}|p{0.70\linewidth}| .. list-table:: :header-rows: 1 :widths: 30 70 * - Test method - Description * - \ :ref:`ImplementsOfTestByLayerTestingServiceWithSpringTest`\ - Test is performed by injecting \ ``Service``\ and joining infrastructure layers. * - \ :ref:`ImplementsOfTestByLayerTestingServiceWithMockito`\ - Test is performed by mocking all the classes on which implementation class of \ ``Service``\ depends. Explanation is given by using the test for following deliverables as an example. Further, for details of Service implementation, refer \ :ref:`service-label`\. * Implementation class of Service (\ ``TicketReserveServiceImpl``\) An implementation example for test is shown below. * ``TicketReserveServiceImpl.java`` .. code-block:: java @Service @Transactional public class TicketReserveServiceImpl implements TicketReserveService { @Inject ReservationRepository reservationRepository; @Override public TicketReserveDto registerReservation(Reservation reservation) throws BusinessException { List reserveFlightList = reservation.getReserveFlightList(); // repository access int reservationInsertCount = reservationRepository.insert(reservation); if (reservationInsertCount != 1) { throw new SystemException(LogMessages.E_AR_A0_L9002.getCode(), LogMessages.E_AR_A0_L9002.getMessage(reservationInsertCount, 1)); } String reserveNo = reservation.getReserveNo(); Date paymentDate = reserveFlightList.get(0).getFlight().getDepartureDate(); return new TicketReserveDto(reserveNo, paymentDate); } } Mapping file used for test is shown below. * ``ReservationRepository.xml`` .. code-block:: xml SELECT TO_CHAR(NEXTVAL('sq_reservation_1'), 'FM0999999999') INSERT INTO reservation ( reserve_no, reserve_date, total_fare, rep_family_name, rep_given_name, rep_age, rep_gender, rep_tel, rep_mail, rep_customer_no ) VALUES ( #{reserveNo}, #{reserveDate}, #{totalFare}, #{repFamilyName}, #{repGivenName}, #{repAge}, #{repGender.code}, #{repTel}, #{repMail}, NULLIF(#{repMember.membershipNumber}, '') ) .. _ImplementsOfTestByLayerTestingServiceWithSpringTest: Test using dependent class '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Test is performed by injecting \ ``Service``\ and joining infrastructure layers. Files created for \ ``Service``\ test are shown below. .. figure:: ./images/ImplementsOfTestByLayerServiceSpringTestItems.png .. tabularcolumns:: |p{0.30\linewidth}|p{0.70\linewidth}| .. list-table:: :header-rows: 1 :widths: 30 70 * - Names of files to be created - Description * - \ ``TicketReserveServiceImplTest.java``\ - Test class of \ ``TicketReserveServiceImpl.java``\ * - \ ``test-context.xml``\ - Use setup file defined in \ :ref:`PreparationForTestMakeSettingFileForSpringTest`\. | A test creation method is explained wherein the test is performed by injecting Service implementation class for test and joining infrastructure layers. Setup files read at the time of testing are shown below. * ``sample-domain.xml`` .. code-block:: xml Test implementation example is shown below. Run \ ``TicketReserveServiceImpl#registerReservation()``\ method for test and verify the return value. Further, for how to verify database status, refer \ :ref:`ImplementsOfTestByLayerUnitTestOfRepository`\. * ``TicketReserveServiceImplTest.java`` .. code-block:: java import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:META-INF/spring/sample-domain.xml", // (1) "classpath:META-INF/spring/test-context.xml"}) // (1) @Transactional public class TicketReserveServiceImplTest { @Inject TicketReserveService target; @Inject private JdbcTemplate jdbcTemplate; @Test @Sql(statements = "ALTER SEQUENCE sq_reservation_1 RESTART WITH 1") // (2) public void testRegisterReservation() { // setup Reservation inputReservation = new Reservation(); inputReservation.setTotalFare(39200); inputReservation.setReserveNo("0000000001"); // omitted // run the test TicketReserveDto actTicketReserveDto = target.registerReservation( reservation); // assertion assertThat(actTicketReserveDto.getReserveNo(), is("0000000001")); // omitted } } .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - Sr. No. - Description * - | (1) - | Read setup file (\ ``sample-domain.xml``\ retained by application and \ ``test-domain.xml``\ supplementing it) required for running \ ``TicketReserveServiceImpl``\ class. * - | (2) - | SQL statement can be directly specified by using \ ``statements``\ attribute of \ ``@Sql``\. Here, the sequence is initialized prior to test method execution. .. warning:: **Transaction management at the time of testing** When \ ``@Transactional``\ annotation is assigned to a test case, steps from start of test execution till end becomes one transaction. Hence, when \ ``Service``\ class assigned with \ ``@Transactional``\ annotation is called from test case, it must be noted that the transaction is inherited from the test case. For example, when the transaction propagation method is default, (\ ``REQUIRED``\),test processes are executed in the transactions started in test case and the timing of the commit and rollback is also considered at the end of the test. For transaction propagation methods, refer \ :ref:`transaction-management-declare-transaction-info-label`\. .. _ImplementsOfTestByLayerTestingServiceWithMockito: Test using mock '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Files to be created in unit test of \ ``Service``\ which is done by mocking all the dependent classes of \ ``Service``\ are shown below. .. figure:: ./images/ImplementsOfTestByLayerServiceMockItems.png .. tabularcolumns:: |p{0.30\linewidth}|p{0.70\linewidth}| .. list-table:: :header-rows: 1 :widths: 30 70 * - Names of files to be created - Description * - \ ``TicketReserveServiceImplMockTest.java``\ - Test class of \ ``TicketReserveServiceImpl.java``\ (while using mock) | How to create a test method while mocking the class that depends on implementation class of \ ``Service``\ for test. Here, mocking is done for \ ``ReservationRepository#insert()``\ method, the method for which the mocking is carried out by \ ``TicketReserveServiceImpl#registerReservation()``\ method is called and return value for testing is verified. * ``TicketReserveServiceImplMockTest.java`` .. code-block:: java import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; public class TicketReserveServiceImplMockTest { @Rule // (1) public MockitoRule mockito = MockitoJUnit.rule(); @Mock // (2) ReservationRepository reservationRepository; @InjectMocks // (3) private TicketReserveServiceImpl target; @Test public void testRegisterReservation() { // setup Reservation inputReservation = new Reservation(); inputReservation.setTotalFare(39200); inputReservation.setReserveNo("0000000001"); // omitted when(reservationRepository.insert(inputReservation)).thenReturn(1); // (4) // run the test TicketReserveDto ticketReserveDto = target.registerReservation(inputReservation); // assertion verify(reservationRepository).insert(inputReservation); // (5) assertThat(ticketReserveDto.getReserveNo(), is("0000000001")); // omitted } } .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - Sr. No. - Description * - | (1) - | Declaration for mock initialization and injection on the basis of annotation. For details, refer \ :ref:`UsageOfLibraryForTestCreateMockObject`\. * - | (2) - | \ ``MemberRepository``\ which depend on \ ``TicketReserveServiceImpl``\ is mocked by assigning \ ``@Mock``\ annotation For details, refer \ :ref:`UsageOfLibraryForTestCreateMockObject`\. * - | (3) - | Mock objects are automatically assigned by assiging \ ``@InjectMocks``\ annotation. For details, refer \ :ref:`UsageOfLibraryForTestCreateMockObject`\. * - | (4) - | When the argument is \ ``inputReservation``\ for \ ``insert``\ method of \ ``ReservationRepository``\, set so as to return "\ ``1``\" as return value. For mocking of method, refer \ :ref:`UsageOfLibraryForTestMockingMethods`\. * - | (5) - | Verify that \ ``insert``\ method of \ ``ReservationRepository``\ has been called once by passing \ ``inputReservation``\ in the argument. For verification of method which is mocked, refer \ :ref:`UsageOfLibraryForTestValidationOfMockMethod`\. | Unit test of application layer ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unit test target for application layer """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" This section explains about unit test of \ :ref:`LayerOfApplication`\ of development guideline. .. figure:: ./images/ImplementsOfTestByLayerLayerOfTestTargetApplication.png :width: 95% A test for verifying logic of \ ``Controller``\ and \ ``Helper``\ is carried out in the application layer. Following items are verified for the \ ``Controller``\. * @RequestMapping (request path, HTTP method and request parameter) * VIEW name to be returned \ ``View``\ is originally included in the application layer, however it is excluded from this guideline. Spring Test provides a support class (\ ``org.springframework.test.web.servlet.MockMvc``\ etc) for testing controller class. \ ``Controller``\ uses \ ``SpringJUnit4ClassRunner``\ of Spring Test which provides \ ``MockMVC``\, in order to perform test by sending a pseudo request by using \ ``MockMVC``\. \ ``MockMvc``\ consists of a mechanism to send a pseudo request to the \ ``Controller``\ and a test can be performed simulating deployed application. For details of \ ``MockMVC``\, refer \ :ref:`UsageOfLibraryForTestMockMvcOverview`\. .. note:: **Validation test of Form** \ ``Form``\ test should be carried out in a manner similar to actual operation by combining with \ ``Controller``\. If all the patterns of \ ``Validation``\ are combined with \ ``Controller``\, it will increase load on testing. Hence, for a simple \ ``Validation``\ confirmation, \ ``Validation``\ can be verified by \ ``Form``\ unit by separating it from \ ``Controller``\. For test method, \ :ref:`ImplementsOfTestByFunctionTestingBeanValidator`\ can be implemented by using test target. | Unit test of Controller """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Implementation method for unit test of \ ``Controller``\ is explained below. .. tabularcolumns:: |p{0.30\linewidth}|p{0.70\linewidth}| .. list-table:: :header-rows: 1 :widths: 30 70 * - Test method - Description * - \ :ref:`ImplementsOfTestByLayerTestingControllerWithStandaloneSetup`\ - Test is performed by using default context provided by Spring Test and reading specified setup file. * - \ :ref:`ImplementsOfTestByLayerTestingControllerWithWebAppContextSetup`\ - Test is performed using \ ``applicationContext.xml``\ and \ ``spring-mvc.xml``\ which are actually used. * - \ :ref:`ImplementsOfTestByLayerTestingControllerWithMockito`\ - Test is performed by mocking all the classes on which \ ``Controller``\ is dependent. A test example for following deliverables is explained. For details of \ ``Controller``\ implementation, refer \ :ref:`controller-label`\. * \ ``Controller``\ class (TicketSearchController) * \ ``Controller``\ class (MemberRegisterController) Note that, when you want to carry out test by combining injection and mocking, implement the same by combining following implementation methods as appropriate. .. _ImplementsOfTestByLayerTestingControllerWithStandaloneSetup: Test using StandaloneSetup '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' For the unit test of \ ``Controller``\ when the dependency class of \ ``Controller``\ can be used without the necessity of mocking, files to be created by \ ``StandaloneSetup``\ are as below. .. figure:: ./images/ImplementsOfTestByLayerControllerStandaloneSetupItems.png .. tabularcolumns:: |p{0.50\linewidth}|p{0.50\linewidth}| .. list-table:: :header-rows: 1 :widths: 50 50 * - Names of files to be created - Description * - \ ``MemberRegisterControllerStandaloneTest.java``\ - Test class of \ ``MemberRegisterController.java``\ * - \ ``spring-mvc-test.xml``\ - Setup file which extracts \ ``component-scan``\ for test, in order to read application layer dependent components. * - \ ``test-context.xml``\ - Setup file to be used while testing \ ``Controller``\ with domain layer and infrastructure layer. | It is preferable to perform test by using \ ``spring-mvc.xml``\, however context created by Spring Test and context created by Spring MVC may conflict and test execution might not be possible. As a countermeasure, only the settings necessary for testing are extracted and a setting file for test is provided. Setup files for which only necessary settings are extracted are shown below. * ``spring-mvc-test.xml`` .. code-block:: xml A method to create a test is explained when a class that is dependent on the \ ``Controller``\ class for testing such as \ ``ServiceImpl``\ is to be injected. Note that, for verification method while accessing data in the test, refer \ :ref:`ImplementsOfTestByLayerUnitTestOfRepository`\ and for the method of verifying logic of domain layer to be called, refer \ :ref:`ImplementsOfTestByLayerUnitTestOfService`\. Implementation example of \ ``Controller``\ for test is shown below. * ``MemberRegisterController.java`` .. code-block:: java @Controller @RequestMapping("member/register") @TransactionTokenCheck("member/register") public class MemberRegisterController { @TransactionTokenCheck(type = TransactionTokenType.IN) @RequestMapping(method = RequestMethod.POST) public String register(@Validated MemberRegisterForm memberRegisterForm, BindingResult result, Model model, RedirectAttributes redirectAttributes) { if (result.hasErrors()) { throw new BadRequestException(result); } // omitted return "redirect:/member/register?complete"; } } Here, \ ``register``\ method of \ ``MemberRegisterController``\ class for testing is called, and it is confirmed that request mapping and returned view is redirected (\ ``testRegisterConfirm01``\) and \ ``BadRequestException``\ is thrown when an invalid value is sent (\ ``testRegisterConfirm02``\). A test method is explained below wherein a class for testing that depends on the \ ``Controller``\ class such as \ ``ServiceImpl``\ class is injected. Further, for verification method while accessing data in the test, refer \ :ref:`ImplementsOfTestByLayerUnitTestOfRepository`\. * ``MemberRegisterControllerStandaloneTest.java`` .. code-block:: java import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:META-INF/spring/applicationContext.xml", // (1) "classpath:META-INF/spring/test-context.xml", // (1) "classpath:META-INF/spring/spring-mvc-test.xml"}) // (1) public class MemberRegisterControllerStandaloneTest { @Inject MemberRegisterController target; MockMvc mockMvc; @Before public void setUp() { // setup mockMvc = MockMvcBuilders.standaloneSetup(target).alwaysDo(log()).build(); // (2) } @Test public void testRegisterConfirm01() throws Exception { // setup and run the test mockMvc.perform(post("/member/register") // omitted .param("password", "testpassword") // (3) .param("reEnterPassword", "testpassword"))) // (3) // assert .andExpect(status().is(302)) // (4) .andExpect(view().name("redirect:/member/register?complete")) // (4) .andExpect(model().hasNoErrors()); // (4) } @Test public void testRegisterConfirm02() throws Exception { try { // setup and run the test mockMvc.perform(post("/member/register") // omitted .param("password", "testpassword") .param("reEnterPassword", "")) // (5) // assert .andExpect(status().is(400)) .andExpect(view().name("common/error/badRequest-error")) .andReturn(); fail("test failure!"); } catch (Exception e) { // assert assertThat(e, is(instanceOf(NestedServletException.class))); // (6) assertThat(e.getCause(), is(instanceOf(BadRequestException.class))); // (6) } } } .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 :class: longtable * - Sr. No. - Description * - | (1) - | Read the setup files (\ ``applicationContext.xml``\ retained by the application and \ ``test-context.xml``\, \ ``spring-mvc-test.xml``\ supplementing the same) required for running \ ``Service``\ dependent on \ ``MemberRegisterController``\ and \ ``Repository``\. \ ``test-context.xml``\ uses \ :ref:`PreparationForTestMakeSettingFileForSpringTest`\. * - | (2) - | Use \ ``Controller``\ generated from loaded Bean definition and setup \ ``MockMvc``\. For setup details, refer \ :ref:`UsageOfLibraryForTestSettingMockMvc`\. * - | (3) - | Send a request by POST method for \ ``member/register``\, in order to call \ ``registerConfirm``\ method of \ ``MemberRegisterController``\ class. Set information of \ ``Form``\ in request parameter. For setup method of request data, refer \ :ref:`UsageOfLibraryForTestSettingOfRequestData`\ and for implementation method for sending a request, refer \ :ref:`UsageOfLibraryForTestExecutionOfRequest`\. * - | (4) - | Use \ ``MvcResult``\ fetched by \ ``andExpect``\ method of \ ``ResultActions``\ returned from \ ``perform``\ method and verify validity of execution results. For details of verification method, refer \ :ref:`UsageOfLibraryForTestImplementationOfExecutionResultVerification`\. * - | (5) - | Send invalid input value. * - | (6) - | Since \ ``SystemExceptionResolver``\ is not enabled, \ ``NestedServletException``\ is notified to servlet container without exception handling. Verify that exception expected in \ ``Controller``\ is thrown from the exception obtained by \ ``getCause``\ method of \ ``NestedServletException``\. | .. _ImplementsOfTestByLayerTestingControllerWithWebAppContextSetup: Test by using WebAppContextSetup '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' For unit test of \ ``Controller``\ when the dependency class of \ ``Controller``\ can be used and mocking is not required, files to be created in \ ``WebAppContextSetup``\ are shown below. .. figure:: ./images/ImplementsOfTestByLayerControllerWebAppContextSetupItems.png .. tabularcolumns:: |p{0.30\linewidth}|p{0.70\linewidth}| .. list-table:: :header-rows: 1 :widths: 30 70 * - Names of files to be created - Description * - \ ``MemberRegisterControllerWebAppContextTest.java``\ - Test class of \ ``MemberRegisterController.java``\ It is possible to check the request to the path and \ ``View``\ name returned by the \ ``Controller``\ in the example of \ :ref:`ImplementsOfTestByLayerTestingControllerWithStandaloneSetup`\,however,since functions which are used by adding to Spring such as \ ``TransactionTokenInterceptor``\ and \ ``SystemExceptionResolver``\ are not applied, it is not possible to determine whether transaction token check is correctly configured or the transition to error page is correct. In such a case, \ ``Interceptor``\ and \ ``ExceptionResolver``\ which are used by adding to Spring can be applied automatically at the time of test, by setting up \ ``MockMvc``\ using \ ``webAppContextSetup``\. Differences after comparing the test explained in \ :ref:`ImplementsOfTestByLayerTestingControllerWithStandaloneSetup`\ and test when \ ``@TransactionTokenCheck``\ annotation and \ ``SystemExceptionResolver``\ are enabled are explained here. Implementation example of \ ``Controller``\ for testing is shown below. * ``MemberRegisterController.java`` .. code-block:: java @Controller @RequestMapping("member/register") @TransactionTokenCheck("member/register") public class MemberRegisterController { @TransactionTokenCheck(type = TransactionTokenType.BEGIN) // (1) @RequestMapping(method = RequestMethod.POST, params = "confirm") public String registerConfirm(@Validated MemberRegisterForm memberRegisterForm, BindingResult result, Model model) { // omitted return "C1/memberRegisterConfirm"; } @TransactionTokenCheck(type = TransactionTokenType.IN) // (1) @RequestMapping(method = RequestMethod.POST) public String register(@Validated MemberRegisterForm memberRegisterForm, BindingResult result, Model model, RedirectAttributes redirectAttributes) { if (result.hasErrors()) { throw new BadRequestException(result); // (2) } // omitted return "redirect:/member/register?complete"; } } .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 :class: longtable * - Sr. No. - Description * - | (1) - | Invalidate invalid requests by setting \ ``@TransactionTokenCheck``\ annotation. For transaction token check, refer \ :ref:`double-submit_transactiontokencheck`\. * - | (2) - | If a validation error occurs at the time of request, it is considered as tampering and an error is thrown. At first, differences in test creation methods when \ ``@TransactionTokenCheck``\ is enabled, are shown below. Further, for verification methods while accessing data in the test, refer \ :ref:`ImplementsOfTestByLayerUnitTestOfRepository`\. * ``MemberRegisterControllerWebAppContextTest.java`` .. code-block:: java import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @RunWith(SpringJUnit4ClassRunner.class) @ContextHierarchy({@ContextConfiguration( // (1) "classpath:META-INF/spring/applicationContext.xml"), // (1) @ContextConfiguration("classpath:META-INF/spring/spring-mvc.xml")}) // (1) @WebAppConfiguration // (1) public class MemberRegisterControllerWebAppContextTest { @Inject WebApplicationContext webApplicationContext; // (2) MockMvc mockMvc; @Before public void setUp() { // setup mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) // (2) .alwaysDo(log()).build(); } @Test public void testRegisterConfirm01() throws Exception { // setup and run the test MvcResult mvcResult = mockMvc.perform(post("/member/register") // (3) .param("confirm", "") // (3) // omitted .param("password", "testpassword") // (3) .param("reEnterPassword", "testpassword")) // (3) // assert .andExpect(status().is(200)) .andExpect(view().name("C1/memberRegisterConfirm")) .andReturn(); TransactionToken actTransactionToken = (TransactionToken) mvcResult.getRequest() .getAttribute(TransactionTokenInterceptor.NEXT_TOKEN_REQUEST_ATTRIBUTE_NAME); // (4) MockHttpSession mockSession = (MockHttpSession) mvcResult.getRequest().getSession(); // (5) // setup and run the test mockMvc.perform(post("/member/register") // (6) // omitted .param("password", "testpassword") // (6) .param("reEnterPassword", "testpassword") // (6) .param(TransactionTokenInterceptor.TOKEN_REQUEST_PARAMETER, actTransactionToken.getTokenString()) // (6) .session(mockSession)) // (6) // assert .andExpect(status().is(302)) // (7) .andExpect(view().name("redirect:/member/register?complete")); // (7) } } .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 :class: longtable * - Sr. No. - Description * - | (1) - | Read \ ``spring-mvc.xml``\ to run \ ``Interceptor``\ and \ ``ExceptionResolver``\ customized for operation. * - | (2) - | Use Web application context generated from loaded Bean definition and set up \ ``MockMvc``\. * - | (3) - | Send a request for the method set by \ ``@TransactionTokenCheck(type = TransactionTokenType.BEGIN)``\ in order to generate a method transaction token. * - | (4) - | Fetch transaction token from request attribute to inherit the transaction token from BEGIN request (\ ``registerConfirm``\ method) to IN request (\ ``register``\ method). * - | (5) - | It is necessary to refer to same session in the next request as well for retaining the transaction token issued by the server side, in the session, however, It is specified in \ ``MockMvc``\ that the same session must be used explicitly as new sessions are used for each request. * - | (6) - | Send the request again to request path (\ ``member/register``\) with the POST method. Set information of \ ``Form``\ and transaction token fetched in (4), in request parameter, and set the session fetched in (5) in the session. * - | (7) - | Verify that the transaction token check error has not occurred to confirm that the settings of transaction token check are correct. | Differences in test creation methods when \ ``SystemExceptionResolver``\ is enabled are explained next. Definition example of \ ``SystemExceptionResolver``\ is shown below. * ``spring-mvc.xml`` .. code-block:: xml org.springframework.web.util.NestedServletException Differences in test creation method are explained below. * ``MemberRegisterControllerWebAppContextTest.java`` .. code-block:: java import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @RunWith(SpringJUnit4ClassRunner.class) @ContextHierarchy({@ContextConfiguration( "classpath:META-INF/spring/applicationContext.xml"), @ContextConfiguration("classpath:META-INF/spring/spring-mvc.xml")}) @WebAppConfiguration public class MemberRegisterControllerWebAppContextTest { @Inject WebApplicationContext webApplicationContext; MockMvc mockMvc; @Before public void setUp() { // setup mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) .alwaysDo(log()).build(); } @Test public void testRegisterConfirm02() throws Exception { // omitted // setup and run the test mvcResult = mockMvc.perform(post("/member/register") .param("password", "testpassword") .param("reEnterPassword", "") // (1) .param(TransactionTokenInterceptor.TOKEN_REQUEST_PARAMETER, actTransactionToken.getTokenString()) // (2) .session(mockSession)) // (2) // assert .andExpect(status().is(400)) // (3) .andExpect(view().name("common/error/badRequest-error")) // (3) .andReturn(); // assert Exception exception = mvcResult.getResolvedException(); // (4) assertThat(exception, is(instanceOf(BadRequestException.class))); // (4) assertThat(exception.getMessage(), is("不正リクエスト(パラメータ改竄)")); // (4) } } .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 :class: longtable * - Sr. No. - Description * - | (1) - | Error is thrown in \ ``register``\ method by making information of \ ``Form``\ invalid value. * - | (2) - | As described earlier, set information of generated transaction token. * - | (3) - | Verify that status code of defined error, transition destination of error page are correctly set since \ ``SystemExceptionResolver``\ is enabled here. * - | (4) - | Verify that the expected error is thrown from the error that handle exceptions in \ ``SystemExceptionResolver``\. .. note:: **When Session is used** When the \ ``Controller``\ class uses a Session, test is performed by using \ ``org.springframework.mock.web.MockHttpSession``\. * Example of test method which use \ ``MockHttpSession``\ .. code-block:: java public class SessionControllerTest { // (1) MockHttpSession mockSession = new MockHttpSession(); // omitted @Test public void testSession() throws Exception { String formName = "todoForm"; TodoForm form = new TodoForm(); String todoId = "1111"; String todoTitle = "test"; form.setTodoId(todoId); form.setTodoTitle(todoTitle); // (2) mockSession.setAttribute(formName, form); // (3) ResultActions results = mockMvc.perform(post("/todo/operation") .param("create", "create") .param("todoId", todoId) .param("todoTitle", todoTitle) .session(mockSession)); // (4) results.andExpect(request().sessionAttribute(formName, isA(TodoForm.class))); // omitted // (5) results = mockMvc.perform(get("/todo/create").param("redo", "redo")); results.andExpect(request().sessionAttribute(formName, isA(TodoForm.class))); // omitted } } .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - Sr. No. - Description * - | (1) - | Generate a mock object of session. For class details, refer \ `MockHttpSession Javadoc `_\. * - | (2) - | Set the object to be stored in the mock object of the generated session. * - | (3) - | Generate a mock request by \ ``post``\ method of \ ``MockMvcRequestBuilders``\ and register a mock session in the generated request by \ ``session``\ method. * - | (4) - | Verify that object set in (2) is stored in the session scope. * - | (5) - | Issue a request again and check whether the object stored in the session scope is retained. | .. _ImplementsOfTestByLayerTestingControllerWithMockito: Test using mock '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Files to be created for unit test of \ ``Controller``\ when it is necessary to mock dependency class of \ ``Controller``\ are as below. .. figure:: ./images/ImplementsOfTestByLayerControllerMockTest.png .. tabularcolumns:: |p{0.30\linewidth}|p{0.70\linewidth}| .. list-table:: :header-rows: 1 :widths: 30 70 * - Names of files to be created - Description * - \ ``TicketSearchControllerMockTest.java``\ - Test class of \ ``TicketSearchController.java``\ | A test creation method when mocking is done for class which is dependent on \ ``Controller``\ class for testing is explained. Implementation example of \ ``Controller``\ for test is shown below. * ``TicketSearchController.java`` .. code-block:: java @Controller @RequestMapping("ticket/search") public class TicketSearchController { @Inject TicketSearchHelper ticketSearchHelper; @RequestMapping(method = RequestMethod.GET, params = "form") public String searchForm(Model model) { model.addAttribute(ticketSearchHelper.createDefaultTicketSearchForm()); model.addAttribute(ticketSearchHelper.createFlightSearchOutputDto()); model.addAttribute("isInitialSearchUnnecessary", true); return "B1/flightSearch"; } } Implementation example for \ ``Controller``\ test is shown below. * ``TicketSearchControllerMockTest.java`` .. code-block:: java import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; public class TicketSearchControllerMockTest { @Rule // (1) public MockitoRule mockito = MockitoJUnit.rule(); @InjectMocks // (2) TicketSearchController target; @Mock // (3) TicketSearchHelper ticketSearchHelper; MockMvc mockMvc; @Before public void setUp() { // setup TicketSearchForm ticketSearchForm = new TicketSearchForm(); ticketSearchForm.setFlightType(FlightType.RT); ticketSearchForm.setDepAirportCd("HND"); // omitted when(ticketSearchHelper.createDefaultTicketSearchForm()).thenReturn(ticketSearchForm); // (4) mockMvc = MockMvcBuilders.standaloneSetup(target).alwaysDo(log()).build(); } @Test public void testSearchForm() throws Exception { // setup and run the test MvcResult mvcResult = mockMvc.perform(get("/ticket/search").param("form", "")) // assert .andExpect(status().is(200)) .andExpect(view().name("B1/flightSearch")) .andReturn(); // assert verify(ticketSearchHelper).createDefaultTicketSearchForm(); // (5) // omitted } } .. tabularcolumns:: |p{0.10\linewidth}|p{0.90\linewidth}| .. list-table:: :header-rows: 1 :widths: 10 90 * - Sr. No. - Description * - | (1) - | Declaration for mock initialization and injection on the basis of annotation. For details, refer \ :ref:`UsageOfLibraryForTestCreateMockObject`\. * - | (2) - | By assigning \ ``@Mock``\ annotation, mocking is done for \ ``TicketSearchHelper``\ which is dependent on \ ``TicketSearchController``\. For details, \ :ref:`UsageOfLibraryForTestCreateMockObject`\. * - | (3) - | By assigning \ ``@InjectMocks``\ annotation, mock objects are automatically assigned. For details, refer \ :ref:`UsageOfLibraryForTestCreateMockObject`\. * - | (4) - | In all test methods, set return value of \ ``createMockForm``\ method as a return value of \ ``createDefaultTicketSearchForm``\ method of \ ``ticketSearchHelper``\ For mocking of method, refer \ :ref:`UsageOfLibraryForTestMockingMethods`\. * - | (5) - | Verify that \ ``createDefaultTicketSearchForm``\ method of \ ``ticketSearchHelper``\ is called once. For verification of method which has undergone mocking, refer\ :ref:`UsageOfLibraryForTestValidationOfMockMethod`\. .. _ImplementsOfTestByLayerUnitTestOfHelper: Unit test of Helper """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Unit test of \ ``Helper``\ can be performed by testing with the implementation same as \ ``Service``\. For implementation method, refer \ :ref:`ImplementsOfTestByLayerUnitTestOfService`\.