所以我有以下代码:
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 方法。
有没有办法以 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) 所以试图了解如何使用 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) 我正在使用 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) 我正在使用 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)
但这似乎不可持续,尤其是当我想稍后添加更多参数或值时。
有没有办法生成详尽的排列,而不是继续循环每个列表?
我正在尝试使用以下命令验证是否未调用函数:
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
,而错误消息显示失败是因为未调用它?为什么反转支票会产生相同的错误?
在 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
但他们期望一个实际的对象。我不知道如何表达我想针对不同的匹配器测试每个元素。
我还检查了检查员,这可能是解决方案,但它们似乎只能帮助立即对列表中的所有元素做出断言。
我正在尝试使用 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
我有两个具有一些共同特征的对象,我想对其进行比较
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 断言来完成所需的功能。
我是序列的新手,所以我可能做了一些(或多或少)非常错误的事情,但我有一个问题:
我写了两个函数:
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_VALUE
为number
.
class MyTestPrime : FunSpec({
context("Prime numbers") { …
Run Code Online (Sandbox Code Playgroud) kotest ×10
kotlin ×9
mockk ×2
testing ×2
unit-testing ×2
bdd ×1
java ×1
junit5 ×1
kotlin-flow ×1
kotlintest ×1
ktor ×1
optimization ×1
sequence ×1