Kotlin协程单元测试执行异常

时间:2020-07-25 10:21:45

标签: java kotlin junit5

Gtihub
可以传递类中的每个函数。但是整个班级都做不到。
WatchService获取文件更改并按频道发送。
Path.subscribe都是通过调试成功完成的。所有路径均已添加到地图。
但是watchKey.pollEvents中没有最后两个文件。而且本地测试失败了
但是测试是通过Github Actions gradle构建通过的。

@Test
fun `file create event should be fired`() {
    var receive: FileEvent<String?>?
    val path = Paths.get("testresources", "create")
    path.file.delete()
    val channel = path.subscribe<String?> {
        converter { path, kind ->
            if (kind != FileEvent.Kind.Delete) {
                return@converter path.file.readText()
            } else {
                return@converter null
            }
        }
    }
    path.file.createNewFile()
    runBlocking {
        withTimeout(5000) {
            receive = channel.receive()
        }
    }
    assertNotNull(receive)
    assertEquals(path.absolutePath, receive!!.path)
    assertEquals(FileEvent.Kind.Create, receive!!.kind)
    assertNotNull(receive!!.data)
    assert(receive!!.data!!.isBlank())
}

ReactiveFile.kt

@ExperimentalCoroutinesApi
object ReactiveFile {
    private val watchService = FileSystems.getDefault().newWatchService()
    private val pathToHandlerMap = mutableMapOf<Path, FileEventChannel<*>>()

    init {
        GlobalScope.launch(Dispatchers.IO) {
            while (true) {
                val watchKey = watchService.take()
                val path = watchKey.watchable()
                if (path is Path) {
                    val pollEvents = watchKey.pollEvents()
                    val events = pollEvents.reversed().distinctBy { it.context() }
                    events.forEach {
                        val currentPath = path.resolve(it.context() as Path).absolutePath
                        val kind = FileEvent.Kind.getByKind(it.kind())
                        if (kind != null) {
                            @Suppress("UNCHECKED_CAST")
                            val fileEventChannel = pathToHandlerMap[currentPath] as? FileEventChannel<Any?>
                            fileEventChannel?.apply {
                                if (isClosedForSend) {
                                    pathToHandlerMap.remove(currentPath)
                                } else {
                                    send(
                                        FileEvent(
                                            path = currentPath,
                                            kind = kind,
                                            data = converter?.invoke(currentPath, kind)
                                        )
                                    )
                                }
                            }
                        }
                    }
                }

                if (!watchKey.reset() || path !is Path) {
                    watchKey.cancel()
                    continue
                }
            }
        }
    }

    fun <T> Path.subscribe(consumer: FileEventChannel<T>.() -> Unit): FileEventChannel<T> {
        val path = this.absolutePath
        path.directory.register(watchService, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE)

        val channel = FileEventChannel<T>()
        consumer(channel)
        pathToHandlerMap[path] = channel
        return channel
    }
}

class FileEventChannel<T>(
    private val channel: Channel<FileEvent<T>> = Channel()
) : Channel<FileEvent<T>> by channel {
    internal var converter: ((path: Path, kind: FileEvent.Kind) -> T)? = null
    fun converter(consumer: (path: Path, kind: FileEvent.Kind) -> T) {
        this.converter = consumer
    }
}

data class FileEvent<T>(
    /**
     * Path of file/directory
     */
    val path: Path,

    /**
     * Kind of event
     */
    val kind: Kind,
    val data: T
) {
    enum class Kind(val kind: WatchEvent.Kind<Path>?) {
        Create(ENTRY_CREATE), Modify(ENTRY_MODIFY), Delete(ENTRY_DELETE);

        companion object {
            fun getByKind(kind: WatchEvent.Kind<*>) = values()
                .filter { it.kind != null }
                .singleOrNull { it.kind!! == kind }
        }
    }
}

我该怎么办?

0 个答案:

没有答案
相关问题