Skip to content

Commit 445d499

Browse files
committed
Introduce autowired class variables
1 parent d7319b0 commit 445d499

7 files changed

Lines changed: 59 additions & 24 deletions

File tree

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,17 @@ class SimpleTestClassModel(
2222

2323
/**
2424
* Extended [SimpleTestClassModel] for Spring analysis reasons
25-
*
26-
* @param injectingMocksClass a class to inject other mocks into
27-
* @param mockedClasses variables of test class to represent mocked instances
2825
*/
2926
class SpringTestClassModel(
3027
classUnderTest: ClassId,
3128
methodTestSets: List<CgMethodTestSet>,
3229
nestedClasses: List<SimpleTestClassModel>,
33-
val thisInstanceModels: TypedModelWrappers = mapOf(),
34-
val thisInstanceDependentMocks: TypedModelWrappers = mapOf(),
30+
val springSpecificInformation: SpringSpecificInformation,
3531
): TestClassModel(classUnderTest, methodTestSets, nestedClasses)
3632

33+
34+
class SpringSpecificInformation(
35+
val thisInstanceModels: TypedModelWrappers = mapOf(),
36+
val thisInstanceDependentMocks: TypedModelWrappers = mapOf(),
37+
val applicationContextModels: TypedModelWrappers = mapOf(),
38+
)

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

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package org.utbot.framework.codegen.domain.models.builders
33
import org.utbot.framework.codegen.domain.UtModelWrapper
44
import org.utbot.framework.codegen.domain.context.CgContext
55
import org.utbot.framework.codegen.domain.models.CgMethodTestSet
6+
import org.utbot.framework.codegen.domain.models.SpringSpecificInformation
67
import org.utbot.framework.codegen.domain.models.SpringTestClassModel
78
import org.utbot.framework.plugin.api.ClassId
89
import org.utbot.framework.plugin.api.UtArrayModel
@@ -11,7 +12,6 @@ import org.utbot.framework.plugin.api.UtClassRefModel
1112
import org.utbot.framework.plugin.api.UtCompositeModel
1213
import org.utbot.framework.plugin.api.UtDirectSetFieldModel
1314
import org.utbot.framework.plugin.api.UtEnumConstantModel
14-
import org.utbot.framework.plugin.api.UtExecutableCallModel
1515
import org.utbot.framework.plugin.api.UtLambdaModel
1616
import org.utbot.framework.plugin.api.UtModel
1717
import org.utbot.framework.plugin.api.UtNullModel
@@ -20,27 +20,32 @@ import org.utbot.framework.plugin.api.UtSpringContextModel
2020
import org.utbot.framework.plugin.api.UtStatementCallModel
2121
import org.utbot.framework.plugin.api.UtVoidModel
2222
import org.utbot.framework.plugin.api.isMockModel
23+
import org.utbot.framework.plugin.api.util.SpringModelUtils.applicationContextClassId
2324

2425
typealias TypedModelWrappers = Map<ClassId, Set<UtModelWrapper>>
2526

2627
class SpringTestClassModelBuilder(val context: CgContext): TestClassModelBuilder() {
2728

2829
override fun createTestClassModel(classUnderTest: ClassId, testSets: List<CgMethodTestSet>): SpringTestClassModel {
2930
val baseModel = SimpleTestClassModelBuilder(context).createTestClassModel(classUnderTest, testSets)
30-
val (thisInstanceModels, dependentMockModels) = collectThisInstanceAndDependentModels(testSets)
31+
val collectedModels = collectModelsForClassVariables(testSets)
3132

3233
return SpringTestClassModel(
3334
classUnderTest = baseModel.classUnderTest,
3435
methodTestSets = baseModel.methodTestSets,
3536
nestedClasses = baseModel.nestedClasses,
36-
thisInstanceModels = thisInstanceModels,
37-
thisInstanceDependentMocks = dependentMockModels
37+
springSpecificInformation = SpringSpecificInformation(
38+
thisInstanceModels = collectedModels.thisInstanceModels,
39+
thisInstanceDependentMocks = collectedModels.thisInstanceDependentMocks,
40+
applicationContextModels = collectedModels.applicationContextModels,
41+
)
3842
)
3943
}
4044

41-
private fun collectThisInstanceAndDependentModels(testSets: List<CgMethodTestSet>): Pair<TypedModelWrappers, TypedModelWrappers> {
45+
private fun collectModelsForClassVariables(testSets: List<CgMethodTestSet>): SpringSpecificInformation {
4246
val thisInstanceModels = mutableSetOf<UtModelWrapper>()
4347
val thisInstancesDependentModels = mutableSetOf<UtModelWrapper>()
48+
val stateBeforeDependentModels = mutableSetOf<UtModelWrapper>()
4449

4550
with(context) {
4651
for ((testSetIndex, testSet) in testSets.withIndex()) {
@@ -51,8 +56,13 @@ class SpringTestClassModelBuilder(val context: CgContext): TestClassModelBuilder
5156
.filterNotNull()
5257
.forEach { model ->
5358
thisInstanceModels += model.wrap()
54-
thisInstancesDependentModels += collectByThisInstanceModel(model)
59+
thisInstancesDependentModels += collectByModel(model)
60+
5561
}
62+
63+
(execution.stateBefore.parameters + setOf(execution.stateBefore.thisInstance))
64+
.filterNotNull()
65+
.forEach { model -> stateBeforeDependentModels += collectByModel(model) }
5666
}
5767
}
5868
}
@@ -65,10 +75,18 @@ class SpringTestClassModelBuilder(val context: CgContext): TestClassModelBuilder
6575
cgModel.model.isMockModel() && cgModel !in thisInstanceModels
6676
}
6777

68-
return thisInstanceModels.groupByClassId() to dependentMockModels.groupByClassId()
78+
val applicationContextModels = stateBeforeDependentModels
79+
.filter { it.model is UtSpringContextModel }
80+
.toSet()
81+
82+
return SpringSpecificInformation(
83+
thisInstanceModels.groupByClassId(),
84+
dependentMockModels.groupByClassId(),
85+
applicationContextModels.groupByClassId(),
86+
)
6987
}
7088

71-
private fun collectByThisInstanceModel(model: UtModel): Set<UtModelWrapper> {
89+
private fun collectByModel(model: UtModel): Set<UtModelWrapper> {
7290
val dependentModels = mutableSetOf<UtModelWrapper>()
7391
collectRecursively(model, dependentModels)
7492

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgAbstractSpringTestClassConstructor.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ abstract class CgAbstractSpringTestClassConstructor(context: CgContext):
8585
abstract fun constructAdditionalMethods(): CgMethodsCluster
8686

8787
protected fun constructFieldsWithAnnotation(
88+
annotationClassId: ClassId,
8889
groupedModelsByClassId: TypedModelWrappers,
89-
annotationClassId: ClassId
9090
): List<CgFieldDeclaration> {
9191
require(
9292
annotationClassId == injectMocksClassId ||
@@ -114,6 +114,7 @@ abstract class CgAbstractSpringTestClassConstructor(context: CgContext):
114114
when (annotationClassId) {
115115
injectMocksClassId -> variableConstructor.injectedMocksModelsVariables += listOfUtModels
116116
mockClassId -> variableConstructor.mockedModelsVariables += listOfUtModels
117+
autowiredClassId -> variableConstructor.autowiredVariables += listOfUtModels
117118
}
118119
}
119120

@@ -134,7 +135,8 @@ abstract class CgAbstractSpringTestClassConstructor(context: CgContext):
134135
val whiteListOfModels =
135136
listOf(
136137
variableConstructor.mockedModelsVariables,
137-
variableConstructor.injectedMocksModelsVariables
138+
variableConstructor.injectedMocksModelsVariables,
139+
variableConstructor.autowiredVariables,
138140
).flatten()
139141

140142
valueByUtModelWrapper

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgSpringIntegrationTestClassConstructor.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import org.utbot.framework.codegen.domain.models.SpringTestClassModel
99
class CgSpringIntegrationTestClassConstructor(context: CgContext) : CgAbstractSpringTestClassConstructor(context) {
1010

1111
override fun constructClassFields(testClassModel: SpringTestClassModel): List<CgFieldDeclaration> {
12-
return constructFieldsWithAnnotation(testClassModel.thisInstanceModels, autowiredClassId)
12+
val applicationContextModels = testClassModel.springSpecificInformation.applicationContextModels
13+
return constructFieldsWithAnnotation(autowiredClassId, applicationContextModels)
1314
}
1415

1516
override fun constructAdditionalMethods() = CgMethodsCluster(

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgSpringUnitTestClassConstructor.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@ class CgSpringUnitTestClassConstructor(context: CgContext) : CgAbstractSpringTes
2727

2828
override fun constructClassFields(testClassModel: SpringTestClassModel): List<CgFieldDeclaration> {
2929
val fields = mutableListOf<CgFieldDeclaration>()
30+
val thisInstances = testClassModel.springSpecificInformation.thisInstanceModels
31+
val mocks = testClassModel.springSpecificInformation.thisInstanceDependentMocks
3032

31-
if (testClassModel.thisInstanceDependentMocks.isNotEmpty()) {
32-
val mockedFields = constructFieldsWithAnnotation(testClassModel.thisInstanceDependentMocks, mockClassId)
33-
val injectingMocksFields = constructFieldsWithAnnotation(testClassModel.thisInstanceModels, injectMocksClassId)
33+
if (mocks.isNotEmpty()) {
34+
val mockedFields = constructFieldsWithAnnotation(mockClassId, mocks)
35+
val injectingMocksFields = constructFieldsWithAnnotation(injectMocksClassId, thisInstances)
3436

3537
fields += injectingMocksFields
3638
fields += mockedFields

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgSpringVariableConstructor.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,9 @@ import org.utbot.framework.plugin.api.isMockModel
1313
class CgSpringVariableConstructor(context: CgContext) : CgVariableConstructor(context) {
1414
val injectedMocksModelsVariables: MutableSet<UtModelWrapper> = mutableSetOf()
1515
val mockedModelsVariables: MutableSet<UtModelWrapper> = mutableSetOf()
16+
val autowiredVariables: MutableSet<UtModelWrapper> = mutableSetOf()
1617

1718
override fun getOrCreateVariable(model: UtModel, name: String?): CgValue {
18-
if (model is UtSpringContextModel) {
19-
// TODO also, properly render corresponding @Autowired field(s), and make sure name isn't taken
20-
return CgVariable(model.modelName, model.classId)
21-
}
22-
2319
val alreadyCreatedInjectMocks = findCgValueByModel(model, injectedMocksModelsVariables)
2420
if (alreadyCreatedInjectMocks != null) {
2521
val fields: Collection<UtModel> = when (model) {
@@ -45,6 +41,11 @@ class CgSpringVariableConstructor(context: CgContext) : CgVariableConstructor(co
4541
return alreadyCreatedMock
4642
}
4743

44+
val alreadyCreatedAutowired = findCgValueByModel(model, autowiredVariables)
45+
if (alreadyCreatedAutowired != null) {
46+
return alreadyCreatedAutowired
47+
}
48+
4849
return super.getOrCreateVariable(model, name)
4950
}
5051

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgVariableConstructor.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import org.utbot.framework.plugin.api.UtModel
5252
import org.utbot.framework.plugin.api.UtNullModel
5353
import org.utbot.framework.plugin.api.UtPrimitiveModel
5454
import org.utbot.framework.plugin.api.UtReferenceModel
55+
import org.utbot.framework.plugin.api.UtSpringContextModel
5556
import org.utbot.framework.plugin.api.UtStatementCallModel
5657
import org.utbot.framework.plugin.api.UtVoidModel
5758
import org.utbot.framework.plugin.api.util.classClassId
@@ -114,6 +115,7 @@ open class CgVariableConstructor(val context: CgContext) :
114115
return when (model) {
115116
is UtCompositeModel -> constructComposite(model, baseName)
116117
is UtAssembleModel -> constructAssemble(model, baseName)
118+
is UtSpringContextModel -> constructSpringContext(model, baseName)
117119
is UtArrayModel -> constructArray(model, baseName)
118120
is UtEnumConstantModel -> constructEnumConstant(model, baseName)
119121
is UtClassRefModel -> constructClassRef(model, baseName)
@@ -232,6 +234,13 @@ open class CgVariableConstructor(val context: CgContext) :
232234
return valueByUtModelWrapper.getValue(model.wrap())
233235
}
234236

237+
private fun constructSpringContext(model: UtSpringContextModel, baseName: String?): CgValue {
238+
val obj = newVar(model.classId, baseName) { utilsClassId[createInstance](model.classId.name) }
239+
240+
valueByUtModelWrapper[model.wrap()] = obj
241+
return obj
242+
}
243+
235244
private fun processInstantiationStatement(
236245
model: UtAssembleModel,
237246
statementCall: UtStatementCallModel,

0 commit comments

Comments
 (0)