Kotlin 跨 junit 测试共享伴随对象

Posted

技术标签:

【中文标题】Kotlin 跨 junit 测试共享伴随对象【英文标题】:Kotlin shared companion object across junit tests 【发布时间】:2018-08-01 22:28:12 【问题描述】:

我有一个集成测试,我将嵌入式 MongoDB 作为伴随对象启动。我想重用这段代码,但我不确定继承是否可行(如果可能的话)。

这是一个 Spring Boot 应用程序:

这是我的测试:

@RunWith(SpringRunner::class)
@SpringBootTest
class RequestRepositoryTest 

@Autowired lateinit var requestRepository: RequestRepository

  companion object 
    private val starter = MongodStarter.getDefaultInstance()
    private var _mongod: MongodProcess? = null
    private var _mongo: MongoClient? = null

    @BeforeClass
    @JvmStatic fun beforeTest()
        val port = 27017
        val _mongodExe = starter.prepare(MongodConfigBuilder()
                .version(Version.Main.DEVELOPMENT)
                .net(Net("localhost", port, Network.localhostIsIPv6()))
                .build())
        _mongod = _mongodExe.start()
        _mongo = MongoClient("localhost", port)
    

    @AfterClass
    @JvmStatic fun afterTest()
        _mongod?.stop()
    
  

  @Test
  fun store() 
    val id = requestRepository.store(Request(requestId = "123"))
    assertNotNull(id)
  


我的存储库类:

@Repository
class RequestRepository @Autowired constructor(val datastore: Datastore) 

  fun store(request : Request) : String = 
  datastore.save(request).id.toString()

所以我的问题是在 Kotlin 中哪种方法是“正确”的。

更新编辑:作为一个外部对象,测试现在看起来更干净了,JUnit 外部资源完全可以跨测试类重用:

谢谢@Lovis

@RunWith(SpringRunner::class)
@SpringBootTest
class RequestRepositoryTest 

  companion object 
      @ClassRule
      @JvmField
      val mongoServer = MongoServer
  

  @Autowired lateinit var requestRepository: RequestRepository

  @Test
  fun store() 
    val id = requestRepository.store(Request(requestId = "123"))
    assertNotNull( id )
    assertTrue  ObjectId.isValid(id) 
  

【问题讨论】:

你想如何“重用”它?在不同的测试班?还是您的意思是针对班级内的不同测试? @Lovis - 在不同的测试类中。 【参考方案1】:

您应该能够使用 jUnit 的 @ClassRuleExternalResource 实现您想要的。不需要 Kotlin 魔法 :-)

在单独的文件中定义object

object MongoServer  : ExternalResource() 
    @Throws(Throwable::class)
    override fun before() 
        // before class
    

    override fun after() 
       // after class
    

然后在每个测试中使用它:

companion object 
    @ClassRule
    @JvmField
    val mongoServer = MongoServer

ClassRule 注释在这里起到了作用,companion object 是使其成为静态所必需的,@JvmField 注释是使该字段公开所必需的。这些是 jUnit 规则系统的限制。

【讨论】:

看起来漂亮整洁。当我有时间尝试时,我会接受答案。谢谢! 它就像一个魅力,代码变得干净且更具可读性!标记为已接受的答案。干杯!

以上是关于Kotlin 跨 junit 测试共享伴随对象的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 JUnit 5 在 Kotlin 中创建 TestContainers 基测试类

Gradle 没有找到我使用 Kotlin 和 JUnit 5 进行的测试

如何在用 Kotlin 编写的 JUnit 5 测试类中注入 Spring bean?

Kotlin + SpringBootTest + Junit 5 + AutoConfigureMockMvc:测试通过时应该失败(似乎@BeforeEach没有生效)

使用 spring boot、kotlin 和 junit 进行休息控制器单元测试

如何使用 SpringBoot2、JUnit5 和 Kotlin 将配置属性注入单元测试