@RunWith(SpringRunner.class)
@WebMvcTest(MyController.class)
@ContextConfiguration(classes = Application.class)
public class MyControllerTest {
@Autowired
MockMvc mockMvc;
@MockBean
EmployeeService employeeService;
@MockBean
EmployeeRepo employeeRepo;
@MockBean
ValidationService validationService;
@Before
public void setup(){
emp=new Employee();
objectMapper=new ObjectMapper();
emp.setId("123");
emp.setAge(100);
emp.setName("pasam");
System.out.println("Employee object before Test"+emp);
}
@Test
public void createEmp() throws Exception{
mockMvc.perform(MockMvcRequestBuilders.post("/sample/insert")
.accept(MediaType.APPLICATION_JSON_VALUE)
.contentType(MediaType.APPLICATION_JSON_VALUE)
.content(objectMapper.writeValueAsString(emp))).andExpect(status().isOk()).andDo(print());
}
}
@RestController
@RequestMapping("/sample")
public class MyController {
@Autowired
private EmployeeService employeeService;
@Autowired
private ValidationService validationService;
@PostMapping(value = "/insert",consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity insertEmployee(@RequestBody Employee employee){
validationService.validateEmp(employee);
employeeService.create(employee);
return ResponseEntity.ok().build();
}
}
public interface ValidationService {
void validateEmp(Employee employee) ;
}
@Slf4j
@Service
public class ValidateServiceImpl implements ValidationService {
@Override
public void validateEmp(Employee employee) {
if(employee.getAge()!=0){
log.info("Age can not be 0");
}
}
}
I am trying to write Test Cases for Spring boot controller by using Spring Runner ,In my controller i want to validate employee object,for that i have written Validate Service interface .Above Test case Passed with validate employee.while debugging above test case.debug point not going into validationServiceImpl class.I want to throw error while Validate Employee Object.How to handle exception in test case.
Actually you mock the ValidationService
dependency :
@MockBean
ValidationService validationService;
And you specify no mock behavior for. So it allows to make the validatorService
dependency to be invoked without throwing any exception. It works as the validateEmp()
method is not designed to return anything required for the workflow of the method under test.
As reminder, a test annotated with WebMvcTest
is designed to focus on the controller testing, not the service testing.
You could remove the @MockBean
annotation to make validationService
the real implementation and not a mock :
ValidationService validationService;
But note that a better way to test unitary the ValidationService
is creating a unit test for it.
At last note also that a still better way would be to use the javax.validation
API to valid the input.
You could annotation in the Employee class to define the constraints on the fields and in the controller to validate the parameter such as :
import javax.validation.Valid;
...
@PostMapping(value = "/insert",consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity insertEmployee(@Valid @RequestBody Employee employe){
// validationService.validateEmp(employee); // Not required any longer
employeeService.create(employee);
return ResponseEntity.ok().build();
}