Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit test rest controller in kotlin + Spring boot

Edit: I've created another class "Utils" and moved function to that class.

class Utils {
fun isMaintenanceFileExist(maintenanceFile: String) : Boolean {
    /** method to check maintenance file, return True if found else False. */
    return File(maintenanceFile).exists()
}
}

I'm testing post API and mocking a method like below:

@Test
fun testMaintenanceMode() {
    val mockUtil = Mockito.mock(Utils::class.java)
    Mockito.`when`(mockUtil.isMaintenanceFileExist("maintenanceFilePath"))
            .thenReturn(true)

    // Request body
    val body = "authId=123&[email protected]&confirmationKey=86b498cb7a94a3555bc6ee1041a1c90a"

    // When maintenance mode is on
    mvc.perform(MockMvcRequestBuilders.post("/post")
            .contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
            .content(body))
            .andExpect(MockMvcResultMatchers.status().isBadRequest)
            .andReturn()
    }

But I'm not getting expected results.

Controller code:

{
utilObj = Utils()
...
@PostMapping("/post")
fun registerByMail(@Valid data: RequestData) : ResponseEntity<Any>
{

    // check for maintenance mode, if True return (error code : 9001)
    if(utilObj.isMaintenanceFileExist("maintenanceFilePath")) {
        println("-------- Maintenance file exist. Exiting. --------")
        var error = ErrorResponse(Response(ResponseCode.MAINTENANCE,
                ResponseCode.MAINTENANCE.toString()))
        return ResponseEntity.badRequest().body(error)
}
...
}

I want to return true from isMaintenanceFileExist() method in test and want to check for badRequest. Please guide how to achieve this.

like image 338
Avv Avatar asked Mar 06 '23 05:03

Avv


1 Answers

From looking at your code snippets I would guess that you're not actually using the mocked Controller instance in your tests. The controller is instantiated by the Spring Boot test runner and not using your mock instance.

I would recommend to extract the isMaintenanceFileExist method into a separate bean and then mock it using @MockBean.

Controller and Util Bean

@RestController
class MyController(@Autowired private val utils: Utils) {

    @PostMapping("/post")
    fun registerByMail(@RequestBody data: String): ResponseEntity<Any> {

        if (utils.isMaintenanceFileExist("maintenanceFilePath")) {
            println("-------- Maintenance file exist. Exiting. --------")
            return ResponseEntity.badRequest().body("error")
        }
        return ResponseEntity.ok("ok")
    }

}

@Component
class Utils {
    fun isMaintenanceFileExist(maintenanceFile: String) = File(maintenanceFile).exists()
}

Test Class

@WebMvcTest(MyController::class)
class DemoApplicationTests {

    @MockBean
    private lateinit var utils: Utils

    @Autowired
    private lateinit var mvc: MockMvc

    @Test
    fun testMaintenanceMode() {
        BDDMockito.given(utils.isMaintenanceFileExist("maintenanceFilePath"))
                .willReturn(true)

        val body = "test"

        mvc.perform(MockMvcRequestBuilders.post("/post")
                .contentType(MediaType.TEXT_PLAIN)
                .content(body))
                .andExpect(MockMvcResultMatchers.status().isBadRequest)
    }

}

See chapter 44.3.7.

like image 181
Michi Gysel Avatar answered Mar 16 '23 15:03

Michi Gysel