diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/services/framework/MockFrameworkManager.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/services/framework/MockFrameworkManager.kt index 6145ebdcf5..95c2fc4518 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/services/framework/MockFrameworkManager.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/services/framework/MockFrameworkManager.kt @@ -183,8 +183,6 @@ private abstract class StaticMocker( private class MockitoMocker(context: CgContext) : ObjectMocker(context) { - private val alreadyMockedModels: MutableSet = Collections.newSetFromMap(IdentityHashMap()) - override fun createMock(model: UtCompositeModel, baseName: String): CgVariable { val modelClass = getClassOf(model.classId) val mockObject = newVar(model.classId, baseName = baseName, isMock = true) { mock(modelClass) } @@ -195,10 +193,6 @@ private class MockitoMocker(context: CgContext) : ObjectMocker(context) { } fun mockForVariable(model: UtCompositeModel, mockObject: CgVariable) { - if (!alreadyMockedModels.add(model)) { - return - } - for ((executable, values) in model.mocks) { val matchers = mockitoArgumentMatchersFor(executable) @@ -225,7 +219,12 @@ private class MockitoMocker(context: CgContext) : ObjectMocker(context) { error("Cannot mock method $executable as it is not accessible from package $testClassPackageName") } - val results = values.map { variableConstructor.getOrCreateVariable(it) }.toTypedArray() + val results = values + .map { value -> + // Sometimes we need mocks returning itself, e.g. for StringBuilder.append method + if (value != model) variableConstructor.getOrCreateVariable(value) else mockObject + } + .toTypedArray() `when`(mockObject[executable](*matchers)).thenReturn(executable.returnType, *results) } else -> error("Only MethodId was expected to appear in simple mocker but got $executable") diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgSpringUnitTestClassConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgSpringUnitTestClassConstructor.kt index a0fd564098..25474ed26b 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgSpringUnitTestClassConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgSpringUnitTestClassConstructor.kt @@ -21,23 +21,32 @@ import org.utbot.framework.plugin.api.util.objectClassId class CgSpringUnitTestClassConstructor(context: CgContext) : CgAbstractSpringTestClassConstructor(context) { + private var additionalMethodsRequired: Boolean = false + private lateinit var mockitoCloseableVariable: CgValue override fun constructClassFields(testClassModel: SpringTestClassModel): List { val fields = mutableListOf() - val mockedFields = constructFieldsWithAnnotation(testClassModel.thisInstanceDependentMocks, mockClassId) - if (mockedFields.isNotEmpty()) { - fields += constructFieldsWithAnnotation(testClassModel.thisInstanceModels, injectMocksClassId) - fields += mockedFields + if (testClassModel.thisInstanceDependentMocks.isNotEmpty()) { + val mockedFields = constructFieldsWithAnnotation(testClassModel.thisInstanceDependentMocks, mockClassId) + val injectingMocksFields = constructFieldsWithAnnotation(testClassModel.thisInstanceModels, injectMocksClassId) + fields += injectingMocksFields + fields += mockedFields fields += constructMockitoCloseables() + + additionalMethodsRequired = true } return fields } override fun constructAdditionalMethods(): CgMethodsCluster { + if (!additionalMethodsRequired) { + return CgMethodsCluster(header = null, content = emptyList(),) + } + importIfNeeded(openMocksMethodId) val openMocksCall = CgMethodCall(