java - 有没有办法在测试之间停止 micronaut 计划的工作?

标签 java kotlin micronaut kotest

我有一个基于属性动态调度作业的应用程序。它监听 ServiceReadyEvent,然后安排作业。下面是一个通过工厂添加到上下文的小示例。

class JobsLoader(
    @param:Named(TaskExecutors.SCHEDULED) val taskScheduler: TaskScheduler,
    val myJobName: String
) : ApplicationEventListener<ServiceReadyEvent> {

    override fun onApplicationEvent(event: ServiceReadyEvent?) {
        taskScheduler.schedule("* * * * *", ()  -> println("running job $jobName"))
    }
}
为了测试这段代码,我使用 kotest 进行了 Micronaut 测试。
@MicronautTest
class Job1Spec(
        @param:Named(TaskExecutors.SCHEDULED) val taskScheduler: TaskScheduler
) {

    init {

        "start job loader" {
            val jobsLoader = JobsLoader("job1", taskScheduler)
            jobsLoader.onApplicationEvent(ServiceReadyEvent(ServiceInstance.of("test", URL("http://localhost:8080"))))
        }

        "verify the job runs" {
            //code here to verify the job ran and performed the correct calls
        }

    }   
}
我还有另一份工作的第二次测试
@MicronautTest
class Job2Spec(
        @param:Named(TaskExecutors.SCHEDULED) val taskScheduler: TaskScheduler
) {

    init {

        "start job loader" {
            val jobsLoader = JobsLoader("job2", taskScheduler)
            jobsLoader.onApplicationEvent(ServiceReadyEvent(ServiceInstance.of("test", URL("http://localhost:8080"))))
        }

        "verify the job runs" {
            //code here to verify the job ran and performed the correct calls
        }

    }   
}
我的问题在于,在第二次测试期间,我看到在第二次测试运行期间仍然安排了第一个作业:
[INFO] 2020-09-10 12:57:00,005 pool-2-thread-1 running job job1
[INFO] 2020-09-10 12:57:00,009 pool-4-thread-1 running job job2 
除了作业的运行之外,关于第一次运行测试的其他一切都已停止。我发现它仍在运行,因为它在作业运行期间由于 HttpClient 被关闭而引发异常。
我试过了
  • 使用 rebuildContext = true 重建测试之间的测试上下文
  • 在我的 JobsLoader 中跟踪预定的 future 类,然后在 afterSpec 中取消它们功能。当我去取消 future 时, future list 总是空的。
  • 手动刷新 TaskScheduler 和 ExecutorService bean

  • 测试都顺利通过,但它们到处都是异常(exception)——尤其是当我开始测试越来越多的工作时,除了我正在测试的工作之外的所有工作都不断失败。我不确定这是否是 kotest、micronaut 测试、调度程序、某种组合或完全其他的问题(我也看到了 vertx 日志,但我认为这不是问题)。我真的只需要想办法在下一次测试运行之前杀死这些作业/线程。
    任何帮助或想法将不胜感激!

    最佳答案

    因此,在输入所有内容后,我几乎立即就发现了我的问题。我在我的测试中手动创建了一个作业,这不是 micronaut 上下文的一部分,所以当我去尝试取消作业时,我的 future 列表总是空的。
    我更改了测试以加载作业并将其添加到上下文中:

    var jobsLoader: JobsLoader? = null
    
        override fun beforeSpec(spec: Spec) {
            jobsLoader = JobsLoader(taskScheduler, getJobsConfiguration(), jobResolver, eventPublisher)
            jobsLoader?.onApplicationEvent(ServiceReadyEvent(ServiceInstance.of("test", URL("http://localhost:8080"))))
            super.beforeSpec(spec)
        }
    
        override fun afterSpec(spec: Spec) {
            jobsLoader?.stopJobs()
            super.afterSpec(spec)
        }
    
    然后在我的作业加载器中提供了一个功能来取消任何作业。
    class JobsLoader(
        @param:Named(TaskExecutors.SCHEDULED) val taskScheduler: TaskScheduler,
        val myJobName: String
    ) : ApplicationEventListener<ServiceReadyEvent> {
    
        private val scheduledJobs = mutableListOf<ScheduledFuture<*>>()
    
        override fun onApplicationEvent(event: ServiceReadyEvent?) {
            val scheduledFuture = taskScheduler.schedule("* * * * *", ()  -> println("running job $jobName"))
            scheduledJobs.add(scheduledFuture)
        }
    
        fun stopJobs() {
            scheduledJobs.forEach { it.cancel(false) }
        }
    }
    

    关于java - 有没有办法在测试之间停止 micronaut 计划的工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63835813/

    相关文章:

    java - 它是方法还是构造函数?

    java - 在执行 Spring Web Flow 时我应该使用 @Controller 类吗

    spring-mvc - 如何使用Spring MVC @RequestParam解析不同的ISO日期/时间格式

    java - Micronaut 是否需要异步编程?

    java - Micronaut SPA Controller

    java - Spring 安全 : session-config with COOKIE not working

    android - 接口(interface)中的属性不能有支持字段

    java - 操作抽象类而不实现

    java - micronaut - java.lang.IllegalAccessError graalvm native 编译外部依赖

    java - 使用数组列表迭代 HashMap ?