【问题标题】:Testing Kotlin Extension Functions with Spring使用 Spring 测试 Kotlin 扩展函数
【发布时间】:2021-10-28 16:59:30
【问题描述】:

我有一个控制器,它根据客户名称获取特定服务:

@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 .../
    }
}

我有一个包含以下内容的文件 Extensions.kt:

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

services.getServiceByCustomer 被称为类似于 `when`(mock.function(anyString())).thenReturn(value) 时,是否可以返回service 的模拟?

我已经尝试使用 mockK 与以下内容:

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

但我认为我没有正确使用它...我目前正在使用com.nhaarman.mockitokotlin2,但尝试过io.mockk

【问题讨论】:

    标签: spring kotlin testing


    【解决方案1】:

    您只需要使用与模拟服务的简单名称实际匹配的customer。您不需要甚至不应该模拟扩展功能。请尝试以下操作:

    class BasicControllerTest {
    
        @MockK
        private lateinit var basicService: BasicService
    
        private lateinit var basicController: BasicController
    
        @BeforeEach
        fun setUp() {
            clearAllMocks()
    
            basicController = BasicController(listOf(basicService))
        }
    }
    

    另外,考虑使用构造函数注入而不是字段注入:

    @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 .../
        }
    }
    

    最后,考虑使用@WebMvcTest 测试控制器,而不是常规的单元测试。在此处查看更多信息https://www.baeldung.com/spring-boot-testing#unit-testing-with-webmvctest

    【讨论】:

    • 谢谢!我确实必须使用“基本”作为客户变量,因为发送到扩展方法的 KClass 是 BasicService 的模拟版本,但这绝对有效。这仅用于控制器代码的单元测试,所以我没有在这里使用@WebMvcTest。当我开始进行集成测试时,我肯定会使用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多