Skip to content

Commit

Permalink
Merge pull request #870 from Chrostoq/unmockall_issue
Browse files Browse the repository at this point in the history
Fix unmockkAll to work if constructor was mocked multiple times
  • Loading branch information
Raibaz committed Jul 29, 2022
2 parents 3adc92e + 62da3ac commit 96d3b93
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 16 deletions.
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

0 comments on commit 96d3b93

Please sign in to comment.