如何在Kotlin中测试使用延迟初始化ID的服务函数?

hgqdbh6s  于 2023-01-26  发布在  Kotlin
关注(0)|答案(1)|浏览(117)

我是Kotlin测试的新手,我想知道如何测试这个函数:
这是我的SegmentService文件:

fun createSegmentFromUserIds(userIds: List<String>, name:String, appId: String): Segmentation {
        val filter = createUserIdFilter(userIds)
        val createSegmentRequest =  CreateSegmentRequest(
            name = name, attribute = filter, type = SegmentType.STATIC
        )
        val segmentation = segmentMetaService.saveSegmentInfo(createSegmentRequest, appId)
        querySegmentService.runUpdateQuery(users = userIds, appId = appId, segmentId = segmentation.id)
        return segmentation
    }

这是saveSegmentInfo函数:

fun saveSegmentInfo(createSegmentFilter: CreateSegmentRequest, appId: String): Segmentation {
    val segmentInfo = segmentationRepository.save(createSegmentFilter.let {
        Segmentation(
            attribute = it.attribute, name = it.name, appId = appId, type = it.type
        )
    })
    logger.info("Segment info saved with id: ${segmentInfo.id}, name: ${segmentInfo.name}")
    return segmentInfo
}

这是细分文档

@Document(Segmentation.COLLECTION_NAME)
class Segmentation(
@Field(ATTRIBUTE)
val attribute: Filter,

@Field(NAME)
val name: String,

@Indexed
@Field(APP_ID)
val appId: String,

@Field(STATUS)
var status: SegmentStatus = SegmentStatus.CREATED,

@Field(TYPE)
var type: SegmentType = SegmentType.STATIC,

@Field(USER_COUNT)
var userCount: Long? = null,
) {
    @Id
    lateinit var id: String

    @Field(CREATION_DATE)
    var creationDate: Date = Date()
}

我已经为它编写了这个测试:

class SegmentServiceTest {
    private val segmentMetaService = mock(SegmentMetaService::class.java)
    private val querySegmentService = mock(QuerySegmentService::class.java)
    private val converterService = mock(ConverterService::class.java)
    private val userAttributeService = mock(UserAttributeService::class.java)
    private val segmentConsumerUserInfoProducer = mock(SegmentConsumerUsersInfoProducer::class.java)
    private val segmentationRepository = mock(SegmentationRepository::class.java)
    @Test
    fun `createSegmentFromUserIds should create a new segment`() {
        val segmentService = SegmentService(
            segmentMetaService = segmentMetaService,
            querySegmentService = querySegmentService,
            converterService = converterService,
            userAttributeService = userAttributeService,
            segmentConsumerUserInfoProducer = segmentConsumerUserInfoProducer
        )

        val userIds = listOf("user-1", "user-2", "user-3")
        val filter = AndFilter(
            operations = listOf(
                AndFilter(
                    operations = listOf(
                        StringListContainsFilter(
                            field = "userId", operationType = StringQueryOperationType.IN, values = userIds
                        )
                    )
                )
            )
        )
        val createSegmentRequest = CreateSegmentRequest(
            name = "segment-name", attribute = filter, type = SegmentType.STATIC
        )
        val segment = Segmentation(attribute = filter, name = "segment-name", type = SegmentType.STATIC, appId = "app-id" )
        `when`(segmentationRepository.save(any())).thenReturn(segment)

        `when`(segmentMetaService.saveSegmentInfo(createSegmentRequest, "app-id")).thenReturn(segment)
        val createdSegment = segmentService.createSegmentFromUserIds(userIds = userIds, name = "segment-name", appId = "app-id")
        assertEquals(segment, createdSegment)
    }
}

但我正面临这样的错误

kotlin.UninitializedPropertyAccessException: lateinit property id has not been initialized

那么我在这里做错了什么呢?我该如何初始化Id?或者我应该重构我的代码使它变得可测试?

uttx8gqw

uttx8gqw1#

我认为你在嘲笑/回答错误的电话。
1.您模拟segmentationRepository.save(..),但不会执行此调用,因为该调用位于segmentMetaService.saveSegmentInfo(...)内部,segmentMetaService.saveSegmentInfo(...)被模拟,因此不会调用真实的的代码。
1.当您调用segmentService.createSegmentFromUserIds(..)时,我的猜测(堆栈跟踪对错误很有用,顺便说一句)是,此方法通过了segmentMetaService.saveSegmentInfo(...)的调用,但在下一行中您调用了querySegmentService.runUpdateQuery(users = userIds, appId = appId, segmentId = segmentation.id),它正在访问未初始化的id
修复方法是在为segmentMetaService.saveSegmentInfo(..)的答案设置对象时设置segment.id

相关问题