Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Kotlin和JUnit5中测试Spring引导缓存_Spring_Spring Boot_Kotlin_Junit5_Spring Cache - Fatal编程技术网

在Kotlin和JUnit5中测试Spring引导缓存

在Kotlin和JUnit5中测试Spring引导缓存,spring,spring-boot,kotlin,junit5,spring-cache,Spring,Spring Boot,Kotlin,Junit5,Spring Cache,我有一个简单的存储库,它的接口是用Kotlin编写的,用于从db获取站点列表;我使用Spring cache缓存响应: interface IRepository { fun sites(): List<String> } @Repository class Repository(private val jdbcTemplate: NamedParameterJdbcTemplate) : IRepository { private val sites = "SE

我有一个简单的存储库,它的接口是用Kotlin编写的,用于从db获取站点列表;我使用Spring cache缓存响应:

interface IRepository {
  fun sites(): List<String>
}

@Repository
class Repository(private val jdbcTemplate: NamedParameterJdbcTemplate) : IRepository {
  private val sites = "SELECT DISTINCT siteId FROM sites"

  @Cacheable(value = ["sites"], key = "sites")
  override fun sites(): List<String> = jdbcTemplate.jdbcTemplate.queryForList(sites, String::class.java)
}
但缓存是空的,并且在第一次读取后不会填充。我的设置中缺少什么

更新:

根据George的建议,我更新了测试(和代码,以便于模拟)。我还必须在配置中为存储库添加
@Bean
,因为
无法自动连线。找不到“Repository”类型的bean。
没有它

  @Cacheable(value = ["sites"], key = "'sites'")
  override fun sites(): List<String> = jdbcTemplate.query(sites) { rs, _ -> rs.getString("siteId") }
更新2:

正如乔治指出的,解决方案是(和)


您正在模拟您的测试主题
存储库
。这应该是Spring初始化的真实对象,因此它具有缓存。您需要模拟测试主体正在调用的
JdbcTemplate

我真的不知道kotlin的语法,所以请耐心听我说。以下是您的测试应该是什么样子:

@ContextConfiguration
@ExtendWith(SpringExtension::class)
class RepositoryCacheTests {
  @MockBean
  private lateinit jdbcTemplate: NamedParameterJdbcTemplate
  @Autowired
  private lateinit var repository: IRepository

  @Autowired
  private lateinit var cache: CacheManager

  @EnableCaching
  @TestConfiguration
  class CachingTestConfig {
    @Bean
    fun cacheManager(): CacheManager = ConcurrentMapCacheManager("sites")
  }

  @Test
  fun `Sites is cached after first read`() {
    // Arrange
    whenever(jdbcTemplate.queryForList(any(), String::class.java)).thenReturn(listOf(site, anotherSite))

    repository.sites()

    // Assert
    assertThat(cache.getCache("sites")?.get("sites")).isNotNull

    //Execute again to test cache.
    repository.sites()
    //JdbcTemplate should have been called once.
    verify(jdbcTemplate, times(1)).queryForList(any(), String::class.java)
  }

1.什么是
repository.read(站点、区域设置)
存储库
类中不存在此方法。2.当您试图从“模板”键检索时,
repository.sites()
调用的结果存储在“site”键下的“site”缓存中。抱歉!我尽量简化这个问题的代码,并复制了错误的方法名。我更新了问题(仍然有效)你说的有道理!我试图听从你的建议,但失败了:(到底是什么失败了?我用你的建议和新的失败更新了问题(BeanNotOfRequiredTypeException for repository)根据这一点,您只需使用接口而不是类:
repository:IRepository
是的,这就是答案。您希望我立即接受您的答案;还是希望更新它,使解决方案出现在答案中,而不出现在注释中?(使用
repository:IRepository
@ContextConfiguration
@ExtendWith(SpringExtension::class)
class RepositoryCacheTests {
  @MockBean
  private lateinit var jdbcTemplate: NamedParameterJdbcTemplate

  @Autowired
  private lateinit var repository: Repository

  @Autowired
  private lateinit var cache: CacheManager

  @EnableCaching
  @TestConfiguration
  class CachingTestConfig {
    @Bean
    fun testRepository(jdbcTemplate: NamedParameterJdbcTemplate): Repository = Repository(jdbcTemplate)

    @Bean
    fun cacheManager(): CacheManager = ConcurrentMapCacheManager("sites")
  }

  @Test
  fun `Sites is cached after first read`() {
    whenever(jdbcTemplate.query(any(), any<RowMapper<String>>())).thenReturn(listOf(site, anotherSite))
    repository.sites()
    assertThat(cache.getCache("sites")?.get("sites")).isNotNull
    repository.sites()
    verify(jdbcTemplate, times(1)).query(any(), any<RowMapper<String>>())
  }
}
Error creating bean with name 'RepositoryCacheTests': Unsatisfied dependency expressed through field 'repository'; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'testRepository' is expected to be of type 'Repository' but was actually of type 'com.sun.proxy.$Proxy52'
  @Autowired
  private lateinit var repository: IRepository
@ContextConfiguration
@ExtendWith(SpringExtension::class)
class RepositoryCacheTests {
  @MockBean
  private lateinit jdbcTemplate: NamedParameterJdbcTemplate
  @Autowired
  private lateinit var repository: IRepository

  @Autowired
  private lateinit var cache: CacheManager

  @EnableCaching
  @TestConfiguration
  class CachingTestConfig {
    @Bean
    fun cacheManager(): CacheManager = ConcurrentMapCacheManager("sites")
  }

  @Test
  fun `Sites is cached after first read`() {
    // Arrange
    whenever(jdbcTemplate.queryForList(any(), String::class.java)).thenReturn(listOf(site, anotherSite))

    repository.sites()

    // Assert
    assertThat(cache.getCache("sites")?.get("sites")).isNotNull

    //Execute again to test cache.
    repository.sites()
    //JdbcTemplate should have been called once.
    verify(jdbcTemplate, times(1)).queryForList(any(), String::class.java)
  }