Search code examples
spring-bootgroovyspock

Spock Testing Framework with Spring Boot to test REST Controller


I have written rest api using spring boot this is controller code

    @RestController
    public class ApiController {
    
        @Autowired
        private ApiService apiService;
        
            @PostMapping(path = "/user", consumes = {MediaType.APPLICATION_JSON_VALUE}, 
produces = {MediaType.APPLICATION_JSON_VALUE})
        @LogTransaction
        public ResponseEntity<String> user(HttpServletRequest request) {
               //apiService.getUser() method call database so i need to mock  it 
               USer user = apiService.getUser(request);
              return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(user);
        }
    }
    

This api is working fine and i have written test using spock framework in groovy

    @SpringBootTest
    class ApiControllerTest extends Specification {
    
    @Autowired
    private ApiController apiController;
    
    @Autowired
    private ApiService apiService;
    
    
    @Autowired
    MockMvc mockMvc
        
    def "User api"() {
            given:
            def User user = new User()      
            apiService.getUser(_) >> user
    
            when:
            def result = mockMvc.perform(MockMvcRequestBuilders
                    .post("/user")
                    .contentType(MediaType.APPLICATION_JSON)
                    .content("""
    {
     "username":"demo",
     "password":"demo"
    }
    """))
                    .andReturn()
    
            then:
            assert result.response.status == HttpStatus.OK.value()
    
    }

This is working fine also. Method apiService.getUser(request) call database . I want to mock it . But it is calling each time to database. So am trying to mock apiService.getUser(request) using @Autowired here but it is not working for me and this method execute each time and call to database. Can anyone share the way to mock apiService.getUser(request) method of controller .


Solution

  • You can partially mock spring beans by annotating them with @SpringSpy.

    So, in your case, all you have to do it replace @Autowired with @SpringSpy:

      @SpringSpy
      private ApiService apiService;
    

    and it should work.