Skip to content

Commit

Permalink
Disallow non-mocks when mock can be used
Browse files Browse the repository at this point in the history
  • Loading branch information
IlyaMuravjov committed Aug 29, 2023
1 parent 5f114ce commit 163e168
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.utbot.framework.context.custom

import org.utbot.framework.context.JavaFuzzingContext
import org.utbot.fuzzer.FuzzedType
import org.utbot.fuzzing.JavaValueProvider
import org.utbot.fuzzing.providers.AnyDepthNullValueProvider
import org.utbot.fuzzing.providers.MapValueProvider
Expand All @@ -13,17 +14,19 @@ import org.utbot.fuzzing.spring.decorators.filterTypes
import org.utbot.instrumentation.instrumentation.execution.UtConcreteExecutionResult

/**
* Allows fuzzer to use mocks in accordance with [JavaFuzzingContext.mockStrategy].
* Makes fuzzer to use mocks in accordance with [mockPredicate].
*
* NOTE:
* - fuzzer won't mock types, that have *specific* value providers (e.g. [MapValueProvider] and [StringValueProvider])
* - [ObjectValueProvider] and [NullValueProvider] do not count as *specific* value providers
* - fuzzer may still resort to mocks despite [mockPredicate] if it can't create other non-null values or at runtime
*/
fun JavaFuzzingContext.allowMocks() =
MockingJavaFuzzingContext(delegateContext = this)
fun JavaFuzzingContext.useMocks(mockPredicate: (FuzzedType) -> Boolean) =
MockingJavaFuzzingContext(delegateContext = this, mockPredicate)

class MockingJavaFuzzingContext(
val delegateContext: JavaFuzzingContext,
val mockPredicate: (FuzzedType) -> Boolean,
) : JavaFuzzingContext by delegateContext {
private val mockValueProvider = MockValueProvider(delegateContext.idGenerator)

Expand All @@ -35,14 +38,8 @@ class MockingJavaFuzzingContext(
.except { it is NullValueProvider }
.except { it is ObjectValueProvider }
.withFallback(
mockValueProvider
.filterTypes { type ->
mockStrategy.eligibleToMock(
classToMock = type.classId,
classUnderTest = classUnderTest
)
}
.with(anyObjectValueProvider(idGenerator))
mockValueProvider.filterTypes(mockPredicate)
.with(anyObjectValueProvider(idGenerator).filterTypes { !mockPredicate(it) })
.withFallback(mockValueProvider.with(AnyDepthNullValueProvider))
.with(NullValueProvider)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import org.utbot.framework.context.ConcreteExecutionContext
import org.utbot.framework.context.NonNullSpeculator
import org.utbot.framework.context.TypeReplacer
import org.utbot.framework.context.custom.CoverageFilteringConcreteExecutionContext
import org.utbot.framework.context.custom.allowMocks
import org.utbot.framework.context.custom.useMocks
import org.utbot.framework.context.utils.transformJavaFuzzingContext
import org.utbot.framework.context.utils.transformValueProvider
import org.utbot.framework.plugin.api.BeanDefinitionData
Expand All @@ -26,10 +26,11 @@ import org.utbot.framework.plugin.api.util.allSuperTypes
import org.utbot.framework.plugin.api.util.id
import org.utbot.framework.plugin.api.util.jClass
import org.utbot.framework.plugin.api.util.utContext
import org.utbot.fuzzing.spring.FuzzedTypeFlag
import org.utbot.fuzzing.spring.addProperties
import org.utbot.fuzzing.spring.decorators.replaceTypes
import org.utbot.fuzzing.spring.properties
import org.utbot.fuzzing.spring.unit.InjectMockValueProvider
import org.utbot.fuzzing.spring.unit.NeverMockFlag
import org.utbot.fuzzing.toFuzzerType

class SpringApplicationContextImpl(
Expand All @@ -42,6 +43,8 @@ class SpringApplicationContextImpl(
private val logger = KotlinLogging.logger {}
}

private object ReplacedFuzzedTypeFlag : FuzzedTypeFlag

override val typeReplacer: TypeReplacer = SpringTypeReplacer(delegateContext.typeReplacer, this)
override val nonNullSpeculator: NonNullSpeculator = SpringNonNullSpeculator(delegateContext.nonNullSpeculator, this)

Expand Down Expand Up @@ -70,7 +73,13 @@ class SpringApplicationContextImpl(
return when (springTestType) {
SpringTestType.UNIT_TEST -> delegateConcreteExecutionContext.transformJavaFuzzingContext { fuzzingContext ->
fuzzingContext
.allowMocks()
.useMocks { type ->
ReplacedFuzzedTypeFlag !in type.properties &&
fuzzingContext.mockStrategy.eligibleToMock(
classToMock = type.classId,
classUnderTest = fuzzingContext.classUnderTest
)
}
.transformValueProvider { origValueProvider ->
InjectMockValueProvider(
idGenerator = fuzzingContext.idGenerator,
Expand All @@ -83,7 +92,7 @@ class SpringApplicationContextImpl(
?.let { replacement ->
// TODO infer generic type of replacement
toFuzzerType(replacement.jClass, description.typeCache).addProperties(
dynamicPropertiesOf(NeverMockFlag.withValue(Unit))
dynamicPropertiesOf(ReplacedFuzzedTypeFlag.withValue(Unit))
)
} ?: type
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,11 @@ import org.utbot.fuzzing.Routine
import org.utbot.fuzzing.Scope
import org.utbot.fuzzing.ScopeProperty
import org.utbot.fuzzing.Seed
import org.utbot.fuzzing.spring.FuzzedTypeFlag
import org.utbot.fuzzing.spring.properties
import org.utbot.fuzzing.spring.utils.jType
import org.utbot.fuzzing.spring.utils.toTypeParametrizedByTypeVariables
import org.utbot.fuzzing.spring.utils.typeToken
import org.utbot.fuzzing.toFuzzerType

object NeverMockFlag : FuzzedTypeFlag

val methodsToMockProperty = ScopeProperty<Set<MethodId>>(
description = "Method ids that can be mocked by `MockValueProvider`"
)
Expand All @@ -41,8 +37,6 @@ class MockValueProvider(private val idGenerator: IdGenerator<Int>) : JavaValuePr

private val methodsToMock = mutableSetOf<MethodId>()

override fun accept(type: FuzzedType) = NeverMockFlag !in type.properties

override fun enrich(description: FuzzedDescription, type: FuzzedType, scope: Scope) {
val publicMethods = type.classId.jClass.methods.map { it.executableId }
publicMethods.intersect(methodsToMock).takeIf { it.isNotEmpty() }?.let {
Expand Down

0 comments on commit 163e168

Please sign in to comment.