Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix unmockkAll to work if constructor was mocked multiple times #870

Merged
merged 2 commits into from Jul 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 1 addition & 8 deletions dsl/common/src/main/kotlin/io/mockk/API.kt
Expand Up @@ -526,7 +526,7 @@ object MockKDsl {

MockKCancellationRegistry
.subRegistry(MockKCancellationRegistry.Type.CONSTRUCTOR)
.putIfNotThere(it, cancellation)
.cancelPut(it, cancellation)
}
}

Expand Down Expand Up @@ -2302,13 +2302,6 @@ object MockKCancellationRegistry {
map[key] = newCancellation
}

fun putIfNotThere(key: Any, newCancellation: MockKCancellation) {
val map = mapTl.value
if (!map.containsKey(key)) {
map[key] = newCancellation
}
}

fun cancelAll() {
val map = mapTl.value
map.values.forEach { it() }
Expand Down
65 changes: 57 additions & 8 deletions mockk/common/src/test/kotlin/io/mockk/it/ConstructorMockTest.kt
Expand Up @@ -3,17 +3,13 @@ package io.mockk.it
import io.mockk.*
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith

class ConstructorMockTest {
class ExampleClass {
val exampleProperty: Int = 1
}

object ExampleObject {
private val exampleClass = ExampleClass()
fun getExampleProperty(): Int = exampleClass.exampleProperty
}

data class MockCls(private val x: Int = 0) {

constructor(x: String) : this(x.toInt())
Expand All @@ -31,16 +27,27 @@ class ConstructorMockTest {

every { anyConstructed<ExampleClass>().exampleProperty } returns 0

assertEquals(0, ExampleObject.getExampleProperty())
assertEquals(0, ExampleClass().exampleProperty)
}

@Test
fun test2() {
fun unmockkAllTest() {
mockkConstructor(ExampleClass::class)
mockkConstructor(ExampleClass::class)

every { anyConstructed<ExampleClass>().exampleProperty } returns 0

assertEquals(0, ExampleObject.getExampleProperty())
assertEquals(0, ExampleClass().exampleProperty)

unmockkAll()

// mockkConstructor called multiple times, but unmockkAll should still be able to unmock it
assertEquals(1, ExampleClass().exampleProperty)

// Constructor not mocked -> MockkException
assertFailsWith<MockKException> {
every { anyConstructed<ExampleClass>().exampleProperty } returns 0
}
}

@Test
Expand Down Expand Up @@ -143,6 +150,48 @@ class ConstructorMockTest {
}
}

@Test
fun unmockkAllconstructedWith() {
mockkConstructor(MockCls::class)
mockkConstructor(MockCls::class)

val checkConstructedWith = { a: Int, b: Int, c: Int ->
every {
constructedWith<MockCls>(OfTypeMatcher<String>(String::class)).op(any(), any())
} returns a
every {
constructedWith<MockCls>(EqMatcher(6)).op(any(), any())
} returns b
every {
constructedWith<MockCls>(OfTypeMatcher<Int>(Int::class)).op(any(), any())
} returns c

assertEquals(a, MockCls("5").op(1, 2))
assertEquals(b, MockCls(6).op(1, 2))
assertEquals(c, MockCls(5).op(1, 2))
}

checkConstructedWith(23, 55, 35)

// New mockkConstructor -> we can still mock as expected
mockkConstructor(MockCls::class)
checkConstructedWith(44, 101, 42)

// mockkConstructor was called multiple times, but we can still unmock it via unmockkAll
unmockkAll()

assertEquals(8, MockCls("5").op(1, 2))
assertEquals(8, MockCls(5).op(1, 2))
assertEquals(9, MockCls(6).op(1, 2))

// Constructor not mocked anymore -> MockkException expected
assertFailsWith<MockKException> {
every {
constructedWith<MockCls>(OfTypeMatcher<String>(String::class)).op(any(), any())
} returns 23
}
}

@Test
fun returnObject() {
mockkConstructor(MockCls::class)
Expand Down