Reputation: 85
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
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