Home > Back-end >  Testing Kotlin Extension Functions with Spring
Testing Kotlin Extension Functions with Spring

Time:10-29

I have a controller that gets a specific service based on a customer name:

@RestController
class BasicController(){

    @Autowired
    private lateinit var services: List<BasicService<*>>

    private var service: BasicService<*>? = null

    @GetMapping("/{customer}")
    fun getAll(@PathVariable customer: String): ResponseEntity<String>{
        service = services.getServiceByCustomer(customer)
        /... code w/return value .../
    }
}

I have a file Extensions.kt with the following:

fun <T: BasicService> List<T>.getServiceByCustomer(customer: String): T?{
    return this.find{
        it::class.simpleName?.contains(customer, ignoreCase = true) == true
    }
}

Is it possible to return a mock of service when services.getServiceByCustomer is called similar to `when`(mock.function(anyString())).thenReturn(value)?

I've tried using mockK with the following:

mockkStatic("path.to.ExtensionsKt")
every {listOf(service).getServiceByCustomer)} returns service

But I don't think I'm using that properly... I'm currently using com.nhaarman.mockitokotlin2 but have tried io.mockk

CodePudding user response:

You just need to use a customer that actually matches the simple name of the mocked service. You don't need or even should mock the extension function. Try the following:

class BasicControllerTest {

    @MockK
    private lateinit var basicService: BasicService

    private lateinit var basicController: BasicController

    @BeforeEach
    fun setUp() {
        clearAllMocks()

        basicController = BasicController(listOf(basicService))
    }
}

Additionally, consider using constructor injection instead of field injection:

@RestController
class BasicController(private val services: List<BasicService<*>>){

    private var service: BasicService<*>? = null

    @GetMapping("/{customer}")
    fun getAll(@PathVariable customer: String): ResponseEntity<String>{
        service = services.getServiceByCustomer(customer)
        /... code w/return value .../
    }
}

Finally, consider testing the Controllers with @WebMvcTest instead of regular unit tests. Check more info here https://www.baeldung.com/spring-boot-testing#unit-testing-with-webmvctest.

  • Related