2

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

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! I did have to use "basic" as the customer variable since the KClass being sent to the extension method was a mocked version of BasicService but this absolutely worked. This was only for unit tests of the controller code so I didn't use @WebMvcTest here. When I start getting into the integration tests I'll be using that for sure.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.