如何模拟存储库以便它不会从数据库中插入或提取数据
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)))
}
}
}
所以我的问题是在我的 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)))
}
}
}