Skip to content

Commit 29fdb41

Browse files
authored
Removed unnecessary mock counter and switch during constructors mocking (#1880)
1 parent 8fb6764 commit 29fdb41

File tree

3 files changed

+43
-11
lines changed

3 files changed

+43
-11
lines changed

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/models/CgElement.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -888,7 +888,8 @@ class CgIfStatement(
888888

889889
data class CgSwitchCaseLabel(
890890
val label: CgLiteral? = null, // have to be compile time constant (null for default label)
891-
val statements: MutableList<CgStatement>
891+
val statements: List<CgStatement>,
892+
val addBreakStatementToEnd: Boolean = true // do not set this field to "true" value if you manually added "break" to statements
892893
) : CgStatement
893894

894895
data class CgSwitchCase(

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/renderer/CgJavaRenderer.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,8 +314,10 @@ internal class CgJavaRenderer(context: CgRendererContext, printer: CgPrinter = C
314314
for (statement in element.statements) {
315315
statement.accept(this)
316316
}
317-
// break statement in the end
318-
CgBreakStatement.accept(this)
317+
318+
if (element.addBreakStatementToEnd) {
319+
CgBreakStatement.accept(this)
320+
}
319321
}
320322
}
321323

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/services/framework/MockFrameworkManager.kt

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import org.utbot.framework.codegen.domain.context.CgContext
2222
import org.utbot.framework.codegen.domain.context.CgContextOwner
2323
import org.utbot.framework.codegen.domain.models.CgAnonymousFunction
2424
import org.utbot.framework.codegen.domain.models.CgAssignment
25+
import org.utbot.framework.codegen.domain.models.CgBreakStatement
2526
import org.utbot.framework.codegen.domain.models.CgConstructorCall
2627
import org.utbot.framework.codegen.domain.models.CgDeclaration
2728
import org.utbot.framework.codegen.domain.models.CgExecutableCall
@@ -226,7 +227,6 @@ private class MockitoStaticMocker(context: CgContext, private val mocker: Object
226227
nameGenerator.variableName(MOCK_CLASS_COUNTER_NAME),
227228
CgConstructorCall(ConstructorId(atomicIntegerClassId, emptyList()), emptyList())
228229
)
229-
+mockClassCounter
230230

231231
val mocksExecutablesAnswers = mock
232232
.instances
@@ -242,13 +242,19 @@ private class MockitoStaticMocker(context: CgContext, private val mocker: Object
242242
mocksExecutablesAnswers,
243243
mockClassCounter.variable
244244
)
245+
246+
if (mockConstructionInitializer.isMockClassCounterRequired) {
247+
// We should insert the counter declaration only if we use this counter, for better readability.
248+
+mockClassCounter
249+
}
250+
245251
val mockedConstructionDeclaration = CgDeclaration(
246252
MockitoStaticMocking.mockedConstructionClassId,
247253
nameGenerator.variableName(MOCKED_CONSTRUCTION_NAME),
248-
mockConstructionInitializer
254+
mockConstructionInitializer.mockConstructionCall
249255
)
250256
resources += mockedConstructionDeclaration
251-
+CgAssignment(mockedConstructionDeclaration.variable, mockConstructionInitializer)
257+
+CgAssignment(mockedConstructionDeclaration.variable, mockConstructionInitializer.mockConstructionCall)
252258
mockedStaticConstructions += classId
253259
}
254260

@@ -317,9 +323,9 @@ private class MockitoStaticMocker(context: CgContext, private val mocker: Object
317323
private fun mockConstruction(
318324
clazz: CgExpression,
319325
classId: ClassId,
320-
mocksWhenAnswers: List<MutableMap<ExecutableId, List<UtModel>>>,
326+
mocksWhenAnswers: List<Map<ExecutableId, List<UtModel>>>,
321327
mockClassCounter: CgVariable
322-
): CgMethodCall {
328+
): MockConstructionBlock {
323329
val mockParameter = variableConstructor.declareParameter(
324330
classId,
325331
nameGenerator.variableName(classId.simpleName, isMock = true)
@@ -333,6 +339,8 @@ private class MockitoStaticMocker(context: CgContext, private val mocker: Object
333339
for ((index, mockWhenAnswers) in mocksWhenAnswers.withIndex()) {
334340
val statements = mutableListOf<CgStatement>()
335341
for ((executable, values) in mockWhenAnswers) {
342+
// For now, all constructors are considered like void methods, but it is proposed to be changed
343+
// for better constructors testing.
336344
if (executable.returnType == voidClassId) continue
337345

338346
when (executable) {
@@ -343,7 +351,7 @@ private class MockitoStaticMocker(context: CgContext, private val mocker: Object
343351
mocker.`when`(mockParameter[executable](*matchers))[thenReturnMethodId](*results)
344352
)
345353
}
346-
else -> error("Expected MethodId but got ConstructorId $executable")
354+
is ConstructorId -> error("Expected MethodId but got ConstructorId $executable")
347355
}
348356
}
349357

@@ -352,15 +360,36 @@ private class MockitoStaticMocker(context: CgContext, private val mocker: Object
352360

353361
val switchCase = CgSwitchCase(mockClassCounter[atomicIntegerGet](), caseLabels)
354362

363+
// If all switch-case labels are empty,
364+
// it means we do not need this switch and mock counter itself at all.
365+
val mockConstructionBody = if (caseLabels.map { it.statements }.all { it.isEmpty() }) {
366+
emptyList()
367+
} else {
368+
listOf(switchCase, CgStatementExecutableCall(mockClassCounter[atomicIntegerGetAndIncrement]()))
369+
}
370+
355371
val answersBlock = CgAnonymousFunction(
356372
voidClassId,
357373
listOf(mockParameter, contextParameter).map { CgParameterDeclaration(it, isVararg = false) },
358-
listOf(switchCase, CgStatementExecutableCall(mockClassCounter[atomicIntegerGetAndIncrement]()))
374+
mockConstructionBody
359375
)
360376

361-
return mockitoClassId[MockitoStaticMocking.mockConstructionMethodId](clazz, answersBlock)
377+
return MockConstructionBlock(
378+
mockitoClassId[MockitoStaticMocking.mockConstructionMethodId](clazz, answersBlock),
379+
mockConstructionBody.isNotEmpty()
380+
)
362381
}
363382

383+
/**
384+
* Represents a body for invocation of the [MockitoStaticMocking.mockConstructionMethodId] method and information
385+
* whether we need to use a counter for different mocking invocations
386+
* (i.e., on each mocking we expect possibly different results).
387+
*/
388+
private data class MockConstructionBlock(
389+
val mockConstructionCall: CgMethodCall,
390+
val isMockClassCounterRequired: Boolean
391+
)
392+
364393
private fun mockStatic(clazz: CgExpression): CgMethodCall =
365394
mockitoClassId[MockitoStaticMocking.mockStaticMethodId](clazz)
366395

0 commit comments

Comments
 (0)