Skip to content

Commit

Permalink
Merge pull request #529 from Jeibniz/Issue-315-Allow-combine-SpyK-Inj…
Browse files Browse the repository at this point in the history
…ectMockKs

Issue 315: Allow to combine @spyk with @InjectMockKs
  • Loading branch information
Raibaz committed Nov 23, 2020
2 parents 8daa101 + a322b26 commit 028afca
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 16 deletions.
29 changes: 29 additions & 0 deletions mockk/common/src/test/kotlin/io/mockk/it/AnnotationsTest.kt
Expand Up @@ -86,6 +86,14 @@ class AnnotationsTest {
val obj = MockCls()
}

class InjectionTarget4{
lateinit var obj: MockCls
fun op(a: Int): Int {
return obj.op(a)
}

}

class InjectSourceCls {
@MockK
lateinit var mock: MockCls
Expand All @@ -112,4 +120,25 @@ class AnnotationsTest {
assertSame(source.mock, source.target2.obj)
assertSame(source.mock, source.target3.obj)
}

class InjectIntoSpySourceCls {
@MockK
lateinit var mock: MockCls

@InjectMockKs
@SpyK
lateinit var target4: InjectionTarget4
}

@Test
fun injectIntoSpy() {
val callValue = 5
val source = InjectIntoSpySourceCls()
MockKAnnotations.init(source)

every { source.mock.op(any()) } returns callValue
assertNotNull(source.target4)
assertEquals(callValue, source.target4.op(0))
verify { source.target4.op(any()) }
}
}
Expand Up @@ -45,11 +45,14 @@ class JvmMockInitializer(val gateway: MockKGateway) : MockKGateway.MockInitializ
relaxed
)
assignRelaxedMockK(property, target)
assignSpyK(
property,
target,
overrideRecordPrivateCalls
)

if (!isAnnotatedWith<InjectMockKs>(property)) {
assignSpyK(
property,
target,
overrideRecordPrivateCalls
)
}
}

for (property in cls.memberProperties) {
Expand All @@ -62,8 +65,8 @@ class JvmMockInitializer(val gateway: MockKGateway) : MockKGateway.MockInitializ
annotation.injectImmutable,
annotation.overrideValues
)

doInjection(property, target, mockInjector)
val instance = doInjection(property, target, mockInjector)
convertSpyKAnnotatedToSpy(property, instance, overrideRecordPrivateCalls)
}
property.annotated<OverrideMockKs>(target) { annotation ->
val mockInjector = MockInjector(
Expand Down Expand Up @@ -99,25 +102,38 @@ class JvmMockInitializer(val gateway: MockKGateway) : MockKGateway.MockInitializ
}
}

private fun convertSpyKAnnotatedToSpy(property: KProperty1<Any, Any>, instance: Any, overrideRecordPrivateCalls: Boolean): Any {
val spyAnnotation = property.findAnnotation<SpyK>() ?: return instance
return createSpyK(property, spyAnnotation, instance, overrideRecordPrivateCalls)
}

private fun assignSpyK(
property: KProperty1<Any, Any>,
target: Any,
overrideRecordPrivateCalls: Boolean
) {
property.annotated<SpyK>(target) { annotation ->
val obj = property.get(target)

gateway.mockFactory.spyk(
null,
obj,
overrideName(annotation.name, property.name),
moreInterfaces(property),
annotation.recordPrivateCalls
|| overrideRecordPrivateCalls
)
createSpyK(property, annotation, obj, overrideRecordPrivateCalls)
}
}

private fun createSpyK(
property: KProperty1<Any, Any>,
spyAnnotation: SpyK,
instance: Any,
overrideRecordPrivateCalls: Boolean
): Any {
return gateway.mockFactory.spyk(
null,
instance,
overrideName(spyAnnotation.name, property.name),
moreInterfaces(property),
spyAnnotation.recordPrivateCalls
|| overrideRecordPrivateCalls
)
}

private fun assignRelaxedMockK(property: KProperty1<Any, Any>, target: Any) {
property.annotated<RelaxedMockK>(target) { annotation ->
val type = property.returnType.classifier as? KClass<*>
Expand Down Expand Up @@ -205,6 +221,11 @@ class JvmMockInitializer(val gateway: MockKGateway) : MockKGateway.MockInitializ
}
}

private inline fun <reified T : Annotation> isAnnotatedWith(property: KProperty<*>) : Boolean {
val annotation = property.findAnnotation<T>()
return null != annotation
}

companion object {
private fun moreInterfaces(property: KProperty1<out Any, Any?>) =
property.annotations
Expand Down

0 comments on commit 028afca

Please sign in to comment.