3

I have Rest Controller with the method create(validation using util class + databaseService(databaseDao + caching))

@RestController
@RequestMapping("files")
public class FilesController {
    private IDbFilesDao dbFilesService;
    private Map<String, Table> tables;

    public FilesController(IDbFilesDao dbFilesService, Map<String, Table> tables) {
        this.dbFilesService = dbFilesService;
        this.tables = tables;
    }

    @PostMapping("{table}")
    public ResponseEntity createTable(@PathVariable("table") String tableName,
                                         @RequestBody File file) {
        FilesValidator.validateAdding(tableName, tables, file);

        dbFilesService.create(tableName, file);

        URI location = ServletUriComponentsBuilder.fromCurrentRequest().buildAndExpand(file.getKey()).toUri();
        return ResponseEntity.created(location).build();
    }
}

I have a Test:

@RunWith(SpringRunner.class)
@WebMvcTest(value = FilesController.class, secure = false)
public class FilesControllerTest {
    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private IDbFilesDao dbFilesService;

    @MockBean
    private Map<String, Table> tables;

    @Test
    public void create() throws Exception {
        RequestBuilder requestBuilder = MockMvcRequestBuilders
                .post("/files/tableName")
                .accept(MediaType.APPLICATION_JSON)
                .content(POST_JSON_BODY)
                .contentType(MediaType.APPLICATION_JSON);
        MvcResult result = mockMvc.perform(requestBuilder).andReturn();
        MockHttpServletResponse response = result.getResponse();
        assertEquals(HttpStatus.CREATED.value(), response.getStatus());
    }
}

It works well only without this row in @RestContoller:

FilesValidator.validateAdding(tableName, tables, file);

With this row - 404 not found.

FilesValidator - util class with static methods. It checks if data is valid and do nothing or throw a Runtime Exception with status code ( 404 for example).

How can I fix it without deliting Validation?

Maciej Kowalski
  • 25,605
  • 12
  • 54
  • 63
Donatello
  • 353
  • 6
  • 19

1 Answers1

3

1) Move the validator call to a package level method and do small refactoring:

@PostMapping("{table}")
    public ResponseEntity createTable(@PathVariable("table") String tableName,
                                         @RequestBody File file) {
        validateAdding(tableName, tables, file);
        ...
}

validateAdding(String tableName, Map<String, Table> tables, File file){
    FilesValidator.validateAdding(tableName, tables, file);
}

2) Spy the controller in the test:

@SpyBean
private FilesController filesControllerSpy;

3) Make validateAdding method do nothing:

@Test
public void create() throws Exception {

   doNothing().when(filesControllerSpy)
     .validateAdding(any(String.class), any(Map.class), any(File.class));
   ...
Maciej Kowalski
  • 25,605
  • 12
  • 54
  • 63
  • It works, thank you! But could I ask something? If I had this class as a Bean with non-static methods instead of util class I could ignore mocking this invocation. Why? Using static i have an exception, using as a bean i can just ignore it. – Donatello Feb 21 '19 at 15:56
  • It means that Mockito.doNothing() and just ignoring it have the same result in case with non-static methods – Donatello Feb 21 '19 at 15:58
  • you could then mock that bean and no more set-up would be needed as void methods of a mock do nothing by default – Maciej Kowalski Feb 21 '19 at 15:59
  • in this case i would have @MockBean which is never used – Donatello Feb 21 '19 at 16:06
  • it would be used but as a mock call which does nothing – Maciej Kowalski Feb 21 '19 at 16:09
  • But as you said, doNothing() and just skiping this step are the same. I need to choose between writting one more useless row in my code(doNothing()) or have @MockBean which is never used (it must be declared in the test class) – Donatello Feb 21 '19 at 16:15