标签: kotest

Kotest 与 Mockk:如何清除验证计数

所以我有以下代码:

When("SMS with location update command is received") {
        every {
            context.getString(R.string.location_sms, any(), any(), any(), any())
        } returns "loc"
        mainServiceViewModel.handleSms(SmsMessage("123", "location"))

        Then("SMS with location is sent to specified phone number") {
            verify(exactly = 1) {
                smsRepository.sendSms("+123", "loc")
            }
        }
    }

    When("motion is detected") {

        Then("information SMS is sent to specified phone number") {
            verify(exactly = 1) {
                smsRepository.sendSms("+123", any())
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

问题在于,尽管第二个案例没有执行任何操作,但这两个案例都通过了。我预计第二种情况会失败,因为甚至没有调用 sendSms 方法。

  1. 如何重置 smsRepository 验证计数?
  2. 如何在每个 When 情况之前重置该计数?

bdd unit-testing kotlin mockk kotest

9
推荐指数
1
解决办法
1万
查看次数

多个断言 (assertAll) - Kotest

有没有办法以 DSL 风格检查 Kotest 中的多个断言 - 没有 JUnit 的 Assertions.assertAll 方法?

我可以写一些类似的东西吗

firstValue shouldBe 1
and secondValue shouldBe 2
Run Code Online (Sandbox Code Playgroud)

代替

assertAll(
    { fistValue shouldBe 1 },
    { secondValue shouldBe 2 })
Run Code Online (Sandbox Code Playgroud)

kotest

5
推荐指数
1
解决办法
2200
查看次数

Ktor 测试无法序列化正文。内容类型为:class ...但需要 OutgoingContent

所以试图了解如何使用 testcontainers 测试 ktor 应用程序

这是我的代码

package com.app

import com.app.base.db.DbFactory
import com.app.features.auth.RegisterDTO
import com.app.plugins.*
import io.kotest.assertions.ktor.client.shouldHaveStatus
import io.kotest.core.extensions.install
import io.kotest.core.spec.style.FreeSpec
import io.kotest.extensions.testcontainers.JdbcTestContainerExtension
import io.ktor.client.*
import io.ktor.client.engine.apache.*
import io.ktor.client.request.*
import io.ktor.http.*
import io.ktor.serialization.kotlinx.json.*
import io.ktor.server.application.*
import io.ktor.server.plugins.contentnegotiation.*
import org.testcontainers.containers.PostgreSQLContainer
import io.ktor.server.testing.*
import kotlinx.serialization.json.Json
import org.jetbrains.exposed.sql.Database

class AuthSpec : FreeSpec({

    val postgres = PostgreSQLContainer<Nothing>("postgres").apply {
        withDatabaseName("test_appDB")
        startupAttempts = 1
        withUsername("test_viktor")
        withPassword("test_longPass")
        withExposedPorts(5432)
    }
    postgres.start()

    val ds = install(JdbcTestContainerExtension(postgres)) {
        poolName = "myconnectionpool"
        maximumPoolSize = 8
        idleTimeout = 10000
    }

    "register creator" - …
Run Code Online (Sandbox Code Playgroud)

serialization kotlin testcontainers ktor kotest

5
推荐指数
1
解决办法
5907
查看次数

kotest更改环境变量

我正在使用 Kotests 为 Ktor 应用程序编写测试,但偶然发现了如何在全局范围内更改测试的环境变量的问题。我尝试过添加withEnvironment,但它给我带来了非常奇怪的错误

Unable to make field private final java.util.Map java.util.Collections$UnmodifiableMap.m accessible: module java.base does not "opens java.util" to unnamed module @3daa422a
java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.util.Map java.util.Collections$UnmodifiableMap.m accessible: module java.base does not "opens java.util" to unnamed module @3daa422a
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
Run Code Online (Sandbox Code Playgroud)

我的测试文件看起来像这样

class VisitorSpec : FreeSpec({
    val ds = createDataSourceTest()

    val visitor = RegisterVisitorDTO(
        email = TestConstants.VISITOR_EMAIL,
        username = TestConstants.VISITOR_USERNAME,
        password = TestConstants.PASSWORD,
        firstName = TestConstants.VISITOR_FIRST_NAME,
        lastName = TestConstants.VISITOR_LAST_NAME,
        gender = …
Run Code Online (Sandbox Code Playgroud)

testing kotlin kotest

5
推荐指数
1
解决办法
1856
查看次数

是否有更简单的方法来使用 Kotest 基于属性的测试来测试所有排列?

我正在使用 kotlin + Kotest 属性测试,并尝试使用列表生成器测试 2 个参数的所有排列,如下所示:

"Some test"{
        forAll(4 ,
                Exhaustive.collection(listOf(
                        "a",
                        "b")),
                Exhaustive.collection(listOf(
                        "1",
                        "2"))
        { begins_with, contains ->
            println("$begins_with:$contains")
            ... some validation code...
        }
Run Code Online (Sandbox Code Playgroud)

我希望使用穷举生成器能够以这样的方式生成它们:通过 4 次迭代,所有可能的排列都将被覆盖。像这样:

a:1
b:2
a:2
b:1
Run Code Online (Sandbox Code Playgroud)

相反,详尽的生成器总是按照列出的顺序排列,如下所示:

a:1
b:2
a:1
b:2
Run Code Online (Sandbox Code Playgroud)

这意味着我正在多次测试同一个案例。

我尝试过将一些生成器切换到 Arb,这确实会切换顺序,但不是最佳状态。为了增加命中所有情况的可能性,我必须进行比使用正确顺序时更多的测试。

我也考虑过像这样多次列出相同的元素

"Some test"{
        forAll(4 ,
                Exhaustive.collection(listOf(
                        "a",
                        "b")),
                Exhaustive.collection(listOf(
                        "1",
                        "1",
                        "2",
                        "2"))
        { begins_with, contains ->
            println("$begins_with:$contains")
            ... some validation code...
        }
Run Code Online (Sandbox Code Playgroud)

但这似乎不可持续,尤其是当我想稍后添加更多参数或值时。

有没有办法生成详尽的排列,而不是继续循环每个列表?

kotlin property-based-testing kotlintest kotest

4
推荐指数
1
解决办法
1463
查看次数

检查调用和未调用时 Mockk 验证失败

我正在尝试使用以下命令验证是否未调用函数:

verify {
    managementService.deleteUser(any()) wasNot Called
}
Run Code Online (Sandbox Code Playgroud)

该验证失败并显示以下消息:

验证失败:第 1 个调用(共 1 个):未调用 ManagementService(#11).deleteUser(any()))。

如果我将验证反转为:

verify {
    managementService.deleteUser(any())
}
Run Code Online (Sandbox Code Playgroud)

我仍然收到相同的失败消息。

ManagementService该通道上还有其他功能wasNot Called也很好。

为什么我的验证会失败wasNot Called,而错误消息显示失败是因为未调用它?为什么反转支票会产生相同的错误?

testing kotlin mockk kotest

4
推荐指数
1
解决办法
1351
查看次数

断言列表包含具有任意顺序的特定属性的元素

在 Junit5 中,我经常使用以下代码片段来测试集合是否包含满足某些条件的元素:

assertThat("The list of addresses", addresses.getAddressReferences(), containsInAnyOrder(
        allOf(
            hasProperty("id", is("abc")),
            hasProperty("role", is(SENDER))
        ),
        allOf(
            hasProperty("id", is("def")),
            hasProperty("role", is(RECEIVER))
        )
    ));
Run Code Online (Sandbox Code Playgroud)

我还没有找到一种方法来在我尝试过的 kotest 中表达这一点,shouldContainExactlyInAnyOrder但他们期望一个实际的对象。我不知道如何表达我想针对不同的匹配器测试每个元素。

我还检查了检查员,这可能是解决方案,但它们似乎只能帮助立即对列表中的所有元素做出断言。

java kotlin junit5 kotest

3
推荐指数
1
解决办法
1774
查看次数

Kotlin Flow:测试挂起

我正在尝试使用 Flows 测试 Kotlin 实现。我使用 Kotest 进行测试。此代码有效:

视图模型:

val detectedFlow = flow<String> {
    emit("123")
    delay(10L)
    emit("123")
}
Run Code Online (Sandbox Code Playgroud)

测试:

class ScanViewModelTest : StringSpec({
    "when the flow contains values they are emitted" {
        val detectedString = "123"
        val vm = ScanViewModel()
        launch {
            vm.detectedFlow.collect {
                it shouldBe detectedString
            }
        }
    }
})
Run Code Online (Sandbox Code Playgroud)

但是,在真正的 ViewModel 中我需要向流添加值,所以我使用ConflatedBroadcastChannel如下:

private val _detectedValues = ConflatedBroadcastChannel<String>()
val detectedFlow = _detectedValues.asFlow()

suspend fun sendDetectedValue(detectedString: String) {
    _detectedValues.send(detectedString)
}
Run Code Online (Sandbox Code Playgroud)

然后在测试中我尝试:

"when the flow contains values they are emitted" …
Run Code Online (Sandbox Code Playgroud)

kotlin kotlin-coroutines kotlin-flow kotest kotlin-coroutines-flow

2
推荐指数
1
解决办法
1558
查看次数

是否有 Kotest 断言来测试列表是否包含具有给定属性的某些元素?

我有两个具有一些共同特征的对象,我想对其进行比较

data class Pet(val colour: String, val owner: Human, val legCount: Int)
data class Car(val colour: String, val owner: Human, val isElectric: Boolean)
Run Code Online (Sandbox Code Playgroud)

我想断言 a 中的某些元素List<Car>包含与给定 具有相同颜色和所有者的元素Pet

这是一个假代码示例来说明我想要做什么:

cars.containsElementSatisfying { car ->
    pet.colour shouldBe car.colour
    pet.owner shouldBe car.owner
}
Run Code Online (Sandbox Code Playgroud)

我该如何使用 kotest 来做到这一点?我可以使用assertJ 的anySatisfy 断言来完成所需的功能。

unit-testing kotlin kotest

2
推荐指数
1
解决办法
4827
查看次数

为什么标准迭代器比 Kotlin 中的序列更快?

我是序列的新手,所以我可能做了一些(或多或少)非常错误的事情,但我有一个问题:

我写了两个函数:

fun isPrimeNumber1(number: Int): Boolean {
    if (number <= 1) return false
    for (divider in 2 .. number / 2) {
        if ( number % divider == 0 ) return false
    }
    return true
}
Run Code Online (Sandbox Code Playgroud)

fun isPrimeNumber2(number: Int): Boolean {
    if (number <= 1) return false
    return !(2 .. number / 2).asSequence().map { it }.any { number % it == 0 }
}
Run Code Online (Sandbox Code Playgroud)

现在我正在运行一个用 编写的测试kotest,其中两个函数都接收Int.MAX_VALUEnumber.

class MyTestPrime : FunSpec({
    context("Prime numbers") { …
Run Code Online (Sandbox Code Playgroud)

optimization sequence kotlin kotest

1
推荐指数
1
解决办法
293
查看次数