【问题标题】:Kotlin & MockK - mocking not working if a mocked method is called from another methodKotlin & MockK - 如果从另一个方法调用模拟方法,则模拟不起作用
【发布时间】:2022-11-27 13:02:35
【问题描述】:

我对 MockK 有疑问。

我有一堂课:

@Service
class ItemServiceImpl(private val varPuObjectMapper: VarPuObjectMapper) : OutboundAdvicesService {

    override suspend fun getItemsForWarehouse(warehouseId: String): ItemsDTO {
        // do stuff
    }

    override suspend fun getPickingListsForWarehouse(warehouseId: String): PickingListsDTO {
        val groupedOutboundAdvices = getItemsForWarehouse(warehouseId)
        // do other stuff
    }
}

和这个类的测试:

class ItemServiceGroupingTest : FunSpec({

    val warehouseId = "1"
    val myObjectMapper = MyObjectMapper()
    val itemService = mockk<ItemServiceImpl>()

    beforeTest {
        val items1 = myObjectMapper
            .getObjectMapper()
            .readValue(Mockups.ITEMS_1, ItemsDTO::class.java)

        coEvery {
            itemService.getItemsForWarehouse(warehouseId)
        } returns items1
    }

    test("should get items for warehouse with ID 1") {
        val itemsDTO = itemService.getItemsForWarehouse(warehouseId)
        // assertions here
    }

    test("should get picking lists for warehouse with ID 1") {
        val pickingLists = itemService.getPickingListsForWarehouse(warehouseId)
        // assertions here
    }
})

现在第一个测试成功通过,但第二个测试失败:

没有找到答案:ItemServiceImpl(#1).getPickingListsForWarehouse(1, continuation {}) io.mockk.MockKException:找不到答案:ItemServiceImpl(#1).getPickingListsForWarehouse(1, continuation {}) 在 app//io.mockk.impl.stub.MockKStub.defaultAnswer(MockKStub.kt:93)

据我了解,这失败是因为 getPickingListsForWarehouse 方法没有被模拟。是否可以使用 MockK 调用真正的方法?我尝试使用 spyk 而不是 mockk,我尝试使用 mockkrelaxed = true,但它让我无处可去......

【问题讨论】:

    标签: unit-testing kotlin mockk kotest


    【解决方案1】:

    第二个测试的问题是您试图在没有指定行为的情况下从模拟中获取方法。第一个测试通过了,因为您已经设置了应该为该方法返回的值:

    itemService.getItemsForWarehouse(warehouseId)
    

    在这里,beforeTest

            coEvery {
                itemService.getItemsForWarehouse(warehouseId)
            } returns items1
    

    你必须对getPickingListsForWarehouse做同样的事情或者调用一个真正的方法,比如:

    every { itemService.getPickingListsForWarehouse(warehouseId) } answers { callOriginal() }
    

    但是你必须使用 spyk 而不是模拟。

    但是,如果您断言您在模拟中提供的对象,则您不是在测试被测方法的真实实现。你只是在测试模拟,所以如果你改变你的方法的实现,这个测试仍然会通过。因为它不是你真正的对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-24
      • 1970-01-01
      • 1970-01-01
      • 2021-11-14
      • 1970-01-01
      相关资源
      最近更新 更多