Shridha Jalihal
Shridha Jalihal

Reputation: 85

Not able to save data in H2 Database using SpringBootTest and Spring JPA Repository

I am using @SpringBootTest to test SpringSecurity basic authentication.When I test it,the h2 database does not save the data.I do not see the insert statement in the console,which I apparently see when I am running my actual SpringBoot Application and inserting the data from frontend. Please help.

Below is my test:

        @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
        @ContextConfiguration(classes=ConnectionsAppApplication.class)
        @Transactional
        public class AuthenticationTest {

            @Autowired
            private WebApplicationContext context;

            private MockMvc mockMvc;

            @Mock
            CustDetailsRepository custRepository;

            @Mock
            BCryptPasswordEncoder encrypt;

            @InjectMocks
            CustomerServiceImpl customerServiceImpl;



           @BeforeEach
           public void setup() {

             MockitoAnnotations.initMocks(this);
             mockMvc = MockMvcBuilders
                .webAppContextSetup(context)
                .apply(springSecurity())
                .build();
           }


          @Test
          void testAuthentication() {

              CustomerDetails customer = new CustomerDetails();
              customer.setEmailid("abc.com");
              customer.setPassword("abc@123456");
              customerServiceImpl.saveUser(customer);
           try {
               this.mockMvc.perform(get("/api/login")
               .with(httpBasic("abc.com","abc@123456")))
               .andDo(print())
               .andExpect(status().isOk())
               .andReturn();
           } catch (Exception e) {
                e.printStackTrace();
            }
         }

       }

saveUser method in CustomerServiceImpl class:

        public void saveUser(CustomerDetails customerDetails) {
          customerDetails.setPassword(bCryptPasswordEncoder.encode(customerDetails.getPassword()));
          custDetailsRepository.save(customerDetails);
         }

Upvotes: 0

Views: 2092

Answers (1)

Lesiak
Lesiak

Reputation: 25976

You have 2 options to implement this test:

Option 1: use real h2

@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
@ContextConfiguration(classes=ConnectionsAppApplication.class)
@Transactional
public class AuthenticationTest {

    @Autowired
    private WebApplicationContext context;

    private MockMvc mockMvc;

    @Autowired
    CustomerServiceImpl customerServiceImpl;

    @BeforeEach
    public void setup() {

        mockMvc = MockMvcBuilders
            .webAppContextSetup(context)
            .apply(springSecurity())
            .build();
    }


    @Test
    void testAuthentication() {

        CustomerDetails customer = new CustomerDetails();
        customer.setEmailid("abc.com");
        customer.setPassword("abc@123456");
        customerServiceImpl.saveUser(customer);
        try {
             this.mockMvc.perform(get("/api/login")
                 .with(httpBasic("abc.com","abc@123456")))
                 .andDo(print())
                 .andExpect(status().isOk())
                 .andReturn();
         } catch (Exception e) {
             e.printStackTrace();
         }
    }
}

Option 2: Mock your service / repository

@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
@ContextConfiguration(classes=ConnectionsAppApplication.class)
@Transactional
public class AuthenticationTest {

    @Autowired
    private WebApplicationContext context;

    private MockMvc mockMvc;

    @MockBean
    CustomerServiceImpl customerServiceImpl;

    @BeforeEach
    public void setup() {
        mockMvc = MockMvcBuilders
            .webAppContextSetup(context)
            .apply(springSecurity())
            .build();
    }


    @Test
    void testAuthentication() {
        // set expectations on CustomerServiceImpl
        CustomerDetails customer = new CustomerDetails();
        customer.setEmailid("abc.com");
        customer.setPassword("abc@123456");
        // mock the method you use to fetch the customer
        when(customerServiceImpl.getUser("abc.com").thenReturn(customer);
        try {
            this.mockMvc.perform(get("/api/login")
                .with(httpBasic("abc.com","abc@123456")))
                .andDo(print())
                .andExpect(status().isOk())
                .andReturn();
           } catch (Exception e) {
                e.printStackTrace();
           }
      }
}

Note that you also can use @WebMvcTest to test only the web slice of your app (meaning no other beans will be instantiated, for example all sercies you depend in the controller must be delivered by @MockBean)

Upvotes: 1

Related Questions