如何模拟存储库以便它不会从数据库中插入或提取数据

How to mock repository so it doesn't instert or pull data from DB

所以我的问题是在我的 SpringBoot REST 应用程序中我正在测试我的 RestController。问题是我不知道如何模拟存储库,因此它不会获取数据或将数据放入数据库。我正在使用 Kotlin 和 Mockk 进行模拟

这是我的存储库

@Repository
interface StandingOrderRepository: CrudRepository<StandingOrder, Int> {

    fun findByNameAndVariableSymbol(name: String, variableSymbol: String): List<StandingOrder>

    fun findByValidFromBetween(fromDate: String, toDate: String): List<StandingOrder>

    fun findByValidFromAfter(fromDate: String) : List<StandingOrder>
}

这是我的测试

    @SpringBootTest
    @AutoConfigureMockMvc
    internal class StandingOrderResourceTest {
    
        @Autowired
        lateinit var mockMvc: MockMvc
        @Autowired
        lateinit var objectMapper: ObjectMapper
    
        private val standingOrderMapper = mockk<StandingOrderMapper>()
        private val standingOrderRepository = mockk<StandingOrderRepository>()
        private val standingOrderServiceImpl = mockk<StandingOrderServiceImpl>()
        private val standingOrderResource = StandingOrderResource(standingOrderServiceImpl)
    
    
        val baseUrl = "/api"
    
        @Nested
        @DisplayName("GetStandingOrders()")
        @TestInstance(TestInstance.Lifecycle.PER_CLASS)
        inner class GetStandingOrders {
            @Test
            fun `should return all StandingOrders`() {
                standingOrderResource.getStandingOrders()
                mockMvc.get(baseUrl)
                    .andDo { print() }
                    .andExpect {
                        status { isOk() }
                        content { contentType(MediaType.APPLICATION_JSON)}
                    }
                //standingOrderResource.getStandingOrders() shouldBe listOf(standingOrderDto)
            }
        }
}

问题是,如果我进行 API 调用或调用模拟存储库,它仍会从 DB

获取实际数据

在您的测试代码中,您应该尝试使用 org.mockito.kotlin 中的方法 whenever() 来存根 StandingOrderRepository 的方法调用。 例如,你的存根代码看起来像这样

whenever(standingOrderRepository.findByNameAndVariableSymbol(any(),any())).thenReturn(listOf(StandingOrder(...)))

UPD:所以你使用 Mockk,然后你应该使用 mockito 中的方法 every 而不是 whenever

这就是我让它工作的方式,也许问题出在我这边,我是如何尝试使用它的@Anton Tokmakov 是正确的,这就是我的做法

@SpringBootTest
@AutoConfigureMockMvc
@ExtendWith(SpringExtension::class)
internal class StandingOrderResourceTest @Autowired constructor(
    val mockMvc: MockMvc,
    val objectMapper: ObjectMapper,
) {

    @MockkBean
    private lateinit var standingOrderResource: StandingOrderResource

    
    @Nested
    @DisplayName("GetStandingOrders()")
    @TestInstance(TestInstance.Lifecycle.PER_CLASS)
    inner class GetStandingOrders {
        @Test
        fun `should return all StandingOrders`() {
            every { standingOrderResource.getStandingOrders() } returns
                    listOf(standingOrderDto1, standingOrderDto2)
            mockMvc.get(baseUrl)
                .andDo { print() }
                .andExpect {
                    status { isOk() }
                    content { contentType(MediaType.APPLICATION_JSON)}
                }
                .andExpect {
                    jsonPath("$..[0]", match(MockMvcResultMatchers.content().json(Gson().toJson(
                        listOf(
                            standingOrderDto1,
                            standingOrderDto2
                        )), false)))
                }
        }
    }