tylerwilson
07/31/2024, 2:51 PMtylerwilson
08/02/2024, 12:59 PMCLOVIS
08/12/2024, 7:00 AMClock
s or allow setting a specific time using an Instant directly) but most things mentioned also works if you're using any other testing library.Sergio Pro
08/12/2024, 4:32 PMMarcus Randevik
09/09/2024, 1:03 PM@Tag(TestCategory.DatabaseTest)
annotation class DatabaseTest {
companion object {
init {
sharedDependency = TestImplementationOfDependency()
}
}
}
The shared dependency is declared as follow in order to be switched out in tests:
var sharedDependency: SharedDependency? = null
val SHARED_DEPENDENCY: SharedDependency
get() {
if (sharedDependency == null) {
sharedDependency = ProductionImplementationOfDependency()
}
return sharedDependency ?: throw RuntimeException("SharedDependency set to null by another thread")
}
When running on java 11, the shared dependency is correctly set to the TestImplementation, this can clearly be seen by placing a breakpoint in the init block. However, when running on java 21 the init block of the tag is not executed. Does anyone have a clue as to why that could be?Guyaume Tremblay
09/13/2024, 1:33 PMactual
in *unitTest
?
My situation is that I have an expect/actual
in an object
which return the user language and I have a test which look for a date (like January 1st
)
My date formater is using this object
and, mokkery can't mock an object. Now, if my computer is not in english but my CI is, my test will fail...
I tried to put an actual in androidUnitTest
but it complain that there is no expect in commonTest
...
Do you think of something else please ?Xavier F. Gouchet
09/20/2024, 11:52 AMOusc
09/30/2024, 9:47 AMkotlin.test
dependency in my local maven repository seems to get lost when I switch between projects (some of them use maven
builds, some use gradle
builds).
the project prompts that kotlin.test
is not found, and refresh gradle dependencies doesn't fix it, the only way I can fix it is by deleting the ~/.m2/org/jetbrains /kotlin/kotlin-test
folder and reloading the gradle project to fix it.
Both my partner and I are experiencing the same issue when running a few specific projects.
Has anyone else encountered this or have any ideas on how to resolve it, it's been bugging me for a long time 😞.Olivier Patry
10/03/2024, 7:01 PMAndroidComposeTestRule
, I'm trying a basic E2E scenario on my app.
The main content stays blank (I get top app bar, bottom nav etc.) until the test finishes, despite using the waitUntil*
helpers.
I have 2 steps in the start sequence to load content: null
(loading), then List<T>
(empty or not), the first step remains until test end but never change before that.
The state relies on a Room database Flow
from a Dao
.
What could prevent the Room flow mechanism to operate in the context of Compose UI tests?SimonT
10/10/2024, 7:21 PMDaniel Weidensdörfer
10/11/2024, 7:27 PMenighma
11/02/2024, 3:15 AMnull
when used instead of the what I've passed to thenReturn
Manuel Lorenzo
11/07/2024, 9:04 PMKrishna Prasad
11/14/2024, 12:27 AMandroidTestImplementation 'androidx.test.espresso:espresso-contrib:3.6.1'
while testing navigation fragmentskgurgul
11/14/2024, 8:44 AMverify
method for KMP without using mocking libraries?Guilherme Delgado
11/20/2024, 12:29 PMjava.lang.AssertionError
when using Asserts with kotlin 2.1.0-RC
or 2.1.0-RC2
. If I downgrade to 2.0.21
it works:
e: .gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/2.1.0-RC2/a2fc741252a95c0b35b2f6803cc4593751adc78f/kotlin-stdlib-2.1.0-RC2.jar!/META-INF/kotlin-stdlib-jdk7.kotlin_moduleModule was compiled with an incompatible version of Kotlin. The binary version of its metadata is 2.1.0, expected version is 1.9.0.
e: .gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/2.1.0-RC2/a2fc741252a95c0b35b2f6803cc4593751adc78f/kotlin-stdlib-2.1.0-RC2.jar!/META-INF/kotlin-stdlib-jdk8.kotlin_moduleModule was compiled with an incompatible version of Kotlin. The binary version of its metadata is 2.1.0, expected version is 1.9.0.
e: .gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/2.1.0-RC2/a2fc741252a95c0b35b2f6803cc4593751adc78f/kotlin-stdlib-2.1.0-RC2.jar!/META-INF/kotlin-stdlib.kotlin_moduleModule was compiled with an incompatible version of Kotlin. The binary version of its metadata is 2.1.0, expected version is 1.9.0.
e: .gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-test-junit/2.1.0-RC2/b93d3ae5bf5d6705f0a7e996ae76625be9aab838/kotlin-test-junit-2.1.0-RC2.jar!/META-INF/kotlin-test_JUnit.kotlin_moduleModule was compiled with an incompatible version of Kotlin. The binary version of its metadata is 2.1.0, expected version is 1.9.0.
e: .gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-test/2.1.0-RC2/589f4d86f57a00236e6af14e85e84f043ca7e41f/kotlin-test-2.1.0-RC2.jar!/META-INF/kotlin-test.kotlin_moduleModule was compiled with an incompatible version of Kotlin. The binary version of its metadata is 2.1.0, expected version is 1.9.0.
Can someone elucidate me? Thanks!David Kubecka
11/22/2024, 3:42 PMassertThat(actual).usingRecursiveComparison().ignoringFields("my.nested.field", MyClass::otherField.name).isEqualTo(expected)
but that is unsatisfactory for two reasons:
• The ignore list is either not type-safe (plain strings) or is too verbose (property references)
• The ignore list needs to be specified on the call site instead of on the declaration side.
The latter point is important in the case of test fixtures which are shared among many tests and which contain some dynamic or computed data, such as dates or hashes. In such cases it would be much more convenient for me if I could ignore the field "on the declaration side, e.g. like this:
my TEST_DATA = MyClass(fixedField = TEST_VALUE, dynamicField = any())
and then use some special assertion function that understands that any()
.
For that to work, I imagine that the return type of any()
should be both a subclass of the dynamicField
type as well some marker type for the assertion function. E.g. in pseudo code
interface AnyMarker
inline fun <reified T> any() = object : T, AnyMarker {}
This looks very similar to how Spring creates proxy classes. That relies on the all-open compiler plugin. But I can't use a similar trick here because
• It would be quite impractical to mark a class with some annotation for the plugin only for the testing use case
• I'm not even sure I can "open" classes such as String
which would be needed for the important ignore-hash use case.
My questions are:
• Does this idea make sense?
• Is it feasible? If yes, how to effectively implement any()
(or something similar)?mbonnin
11/29/2024, 2:42 PM@Test
fun test() = runTest {
CoroutineScope(Dispatchers.Default).launch {
delay(10.seconds)
println("done")
}
}
JVM: completes immediately, without printing "done".
JS: takes 10s and prints done.
Is there a fundamental reason this is like this? Could JS just ignore the launched coroutine? (Or if it's a problem because it has side effects for other tests, shouldn't the bahaviour be the same for JVM?)Romain
12/06/2024, 1:50 AMDavid Kubecka
12/09/2024, 3:52 PMimport org.junit.jupiter.params.provider.Arguments
data class TestData<G, E>(val testName: String, val given: G, val expected: E) {
override fun toString() = testName
}
fun <G, E> List<TestData<G, E>>.asArguments() = map { Arguments.of(it) }
fun myTestMethodTestData() = listOf(
TestData("test case 1", 1, "1"),
TestData("test case 2", 2, "2"),
).asArguments()
This works fine but isn't type-safe, i.e. nothing prevents me from writing
fun myTestMethodTestData() = listOf(
TestData("test case 1", 1, "1"),
TestData("test case 2", "2", 2),
).asArguments()
Is there any way how that can be achieved?
At first I thought I could utilize @NoInfer
to force the user to specify the type arguments explicitly, e.g. asArguments<Int, String>()
, but of course that doesn't enforce anything about the types in the TestData
class instance...martmists
12/14/2024, 3:35 PMPiotr Krzemiński
01/15/2025, 6:30 AMKrishna Prasad
01/16/2025, 11:07 PMaherbel
02/07/2025, 1:34 AMjean
03/04/2025, 11:03 PMDispatchers.setMain(UnconfinedTestDispatcher(testScheduler))
in my test function, it works. But if I use a Rule instead to do it, it fails. I do create the viewmodel from withing the test function and I do have the @get:Rule
as the first thing in the test class. I really don’t understand what I’m doing wrong here. Any idea on what I am missing?Piero Silvestri
03/06/2025, 9:41 AMMeika
03/07/2025, 4:22 AMcommonMain
. right now, we’re leaning towards using Mokkery since it makes migration easier syntax-wise. however, it still requires us to annotate the classes for mocking.
crossposting from #C3PQML5NU since it also make sense to ask hereEd Holloway-George
03/26/2025, 12:02 PM```class FakeRepo: Repo {
private val users = mutableSetOf<String>()
fun addUser(name: String) {
users.add(name)
}
fun getUserCount(): Int {
return users.size
}
}
class SomeService(val repo: Repo) {
fun addUser(name: String) {
userRepository.addUser(name)
}
fun getUserCount(): Int {
return userRepository.getUserCount()
}
}```
If you write tests in this form:
```class SomeServiceTest {
private val repo = FakeRepo()
private val sut = SomeService(repo)
@Test
fun test1() {
service.registerUser("Alice")
val result = sut.getUserCount()
assertEquals(1, result)
}
@Test
fun test2() {
service.registerUser("Bob")
service.registerUser("Charlie")
val result = sut.getUserCount()
assertEquals(2, result)
}
}```
Each individual test will pass if it executes first, but wont pass if it's executed after the other. As the order tests are run isn't guaranteed, this is a common cause of issues with fakes that hold state.Am I right here? The correct approach would be to init
sut
in a @BeforeTest
method right? One of my colleagues mentioned FakeRepo
would be recreated every time without @BeforeTest
Maiko Trindade
04/16/2025, 4:37 PMNino
04/18/2025, 12:24 PMlabel
and other stuff has great value to test.
I would like to avoid overriding the equal function of the data class for obvious reasons.
Any ideas ?
// Source code
data class Foo(
val label: String,
val onClicked: () -> Unit,
val onValueChanged: (Int) -> Unit,
)
object FooMapper {
fun map(
label: String,
viewModel: FooViewModel,
) = Foo(
label = label,
onClicked = { viewModel.onFooClicked() },
onValueChanged = { viewModel.onValueChanged(it.toLong()) },
)
}
class FooViewModel {
fun onFooClicked() { /* whatever */ }
fun onValueChanged(value: Long) { /* whatever */ }
}
// Unit tests
class FooMapperTest {
@Test
fun `foo map`() {
// Given
val label = "label"
val fooViewModel = mockk<FooViewModel>()
// When
val result = FooMapper.map(label = label, viewModel = fooViewModel)
// Then
// !! What should I use there?
assertEquals(
Foo(label = label, onClicked = {}, onValueChanged = {}),
result
)
}
}