Skip to content

Commit b1baf5c

Browse files
committed
Avoid creating too deep dynamic mocks
1 parent b225947 commit b1baf5c

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

utbot-instrumentation/src/main/kotlin/org/utbot/instrumentation/instrumentation/execution/constructors/InstrumentationContextAwareValueConstructor.kt

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ class InstrumentationContextAwareValueConstructor(
7272
private val instrumentationContext: InstrumentationContext,
7373
private val idGenerator: StateBeforeAwareIdGenerator,
7474
) {
75+
companion object {
76+
private const val MAX_DYNAMIC_MOCK_DEPTH = 5
77+
}
78+
7579
private val classLoader: ClassLoader
7680
get() = utContext.classLoader
7781

@@ -249,7 +253,7 @@ class InstrumentationContextAwareValueConstructor(
249253
with(invocation.method) {
250254
mockedExecutables.getOrPut(executableId) {
251255
detectedMockingCandidates.add(executableId)
252-
var answerModel = generateNewAnswerModel(executableId)
256+
var answerModel = generateNewAnswerModel(executableId, dynamicMockModelToDepth[mockModel] ?: 0)
253257
val answerValue = runCatching { constructPrivileged(answerModel) }.getOrElse {
254258
// fallback is used, so we still get some value (null) for types
255259
// that can't be mocked, e.g. arrays and sealed interfaces
@@ -268,15 +272,18 @@ class InstrumentationContextAwareValueConstructor(
268272
}
269273
}
270274

271-
private fun generateNewAnswerModel(executableId: ExecutableId) =
272-
executableId.returnType.defaultValueModel().takeUnless { it.isNull() } ?: when (executableId.returnType) {
275+
private val dynamicMockModelToDepth = mutableMapOf<UtCompositeModel, Int>()
276+
277+
private fun generateNewAnswerModel(executableId: ExecutableId, depth: Int) =
278+
executableId.returnType.defaultValueModel().takeUnless { it.isNull() } ?: when {
273279
// mockito can't mock `String` and `Class`
274-
stringClassId -> UtNullModel(stringClassId)
275-
classClassId -> UtClassRefModel(
280+
executableId.returnType == stringClassId -> UtNullModel(stringClassId)
281+
executableId.returnType == classClassId -> UtClassRefModel(
276282
id = idGenerator.createId(),
277283
classId = classClassId,
278284
value = classClassId,
279285
)
286+
depth > MAX_DYNAMIC_MOCK_DEPTH -> UtNullModel(executableId.classId)
280287

281288
else -> UtCompositeModel(
282289
id = idGenerator.createId(),
@@ -285,7 +292,7 @@ class InstrumentationContextAwareValueConstructor(
285292
classId = executableId.returnType,
286293
isMock = true,
287294
canHaveRedundantOrMissingMocks = true,
288-
)
295+
).also { dynamicMockModelToDepth[it] = depth + 1 }
289296
}
290297

291298
private fun generateMockitoMock(

0 commit comments

Comments
 (0)