From 163e168feea015abacf7a7753d986bc6d83e7f01 Mon Sep 17 00:00:00 2001 From: IlyaMuravjov Date: Tue, 29 Aug 2023 15:15:41 +0300 Subject: [PATCH] Disallow non-mocks when mock can be used --- .../custom/MockingJavaFuzzingContext.kt | 19 ++++++++----------- .../spring/SpringApplicationContextImpl.kt | 17 +++++++++++++---- .../org/utbot/fuzzing/spring/unit/Mocks.kt | 6 ------ 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/context/custom/MockingJavaFuzzingContext.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/context/custom/MockingJavaFuzzingContext.kt index 6c14cdba66..820fb7ac52 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/context/custom/MockingJavaFuzzingContext.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/context/custom/MockingJavaFuzzingContext.kt @@ -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 @@ -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) @@ -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) ) diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/context/spring/SpringApplicationContextImpl.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/context/spring/SpringApplicationContextImpl.kt index 746fb6c706..f0548e523d 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/context/spring/SpringApplicationContextImpl.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/context/spring/SpringApplicationContextImpl.kt @@ -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 @@ -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( @@ -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) @@ -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, @@ -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 } diff --git a/utbot-java-fuzzing/src/main/kotlin/org/utbot/fuzzing/spring/unit/Mocks.kt b/utbot-java-fuzzing/src/main/kotlin/org/utbot/fuzzing/spring/unit/Mocks.kt index 7fa8f0cb13..85417456bf 100644 --- a/utbot-java-fuzzing/src/main/kotlin/org/utbot/fuzzing/spring/unit/Mocks.kt +++ b/utbot-java-fuzzing/src/main/kotlin/org/utbot/fuzzing/spring/unit/Mocks.kt @@ -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>( description = "Method ids that can be mocked by `MockValueProvider`" ) @@ -41,8 +37,6 @@ class MockValueProvider(private val idGenerator: IdGenerator) : JavaValuePr private val methodsToMock = mutableSetOf() - 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 {