From 5a49344af355ce95e3da7c269c44454efd116799 Mon Sep 17 00:00:00 2001 From: Kirill Shishin Date: Fri, 21 Jul 2023 15:01:22 +0300 Subject: [PATCH 1/5] Support autowiring more than one different bean of one type, when Engine output one model for variables of one type. --- .../kotlin/org/utbot/framework/codegen/domain/Domain.kt | 5 ++++- .../utbot/framework/codegen/domain/context/CgContext.kt | 7 ++++--- .../domain/models/builders/SpringTestClassModelBuilder.kt | 8 +++++--- .../codegen/tree/CgAbstractSpringTestClassConstructor.kt | 7 ++----- .../utbot/framework/codegen/tree/CgClassFieldManager.kt | 4 ++-- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/Domain.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/Domain.kt index e94e5c9f5e..f7cb1fb1cd 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/Domain.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/Domain.kt @@ -757,9 +757,12 @@ object SpringBoot : DependencyInjectionFramework( * * Used as a key in [valueByUtModelWrapper]. * Was introduced primarily for shared among all test methods global variables. + * + * `modelTagName` is used to distinguish between variables with annotation @Mock that have the same model */ data class UtModelWrapper( val testSetId: Int, val executionId: Int, - val model: UtModel + val model: UtModel, + val modelTagName: String? ) diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/context/CgContext.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/context/CgContext.kt index 5baae6eee2..4aa883bf97 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/context/CgContext.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/context/CgContext.kt @@ -451,7 +451,7 @@ interface CgContextOwner { val getLambdaMethod: MethodId get() = utilMethodProvider.getLambdaMethodMethodId - fun UtModel.wrap(): UtModelWrapper + fun UtModel.wrap(modelTagName: String? = null): UtModelWrapper } /** @@ -580,11 +580,12 @@ class CgContext( } } - override fun UtModel.wrap(): UtModelWrapper = + override fun UtModel.wrap(modelTagName: String?): UtModelWrapper = UtModelWrapper( testSetId = currentTestSetId, executionId = currentExecutionId, - model = this + model = this, + modelTagName = modelTagName ) private fun createClassIdForNestedClass(testClassModel: SimpleTestClassModel): ClassId { diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/models/builders/SpringTestClassModelBuilder.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/models/builders/SpringTestClassModelBuilder.kt index fd82175d24..a2036a61ca 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/models/builders/SpringTestClassModelBuilder.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/models/builders/SpringTestClassModelBuilder.kt @@ -98,8 +98,8 @@ class SpringTestClassModelBuilder(val context: CgContext): TestClassModelBuilder return classModels } - private fun collectRecursively(currentModel: UtModel, allModels: MutableSet) { - val cgModel = with(context) { currentModel.wrap() } + private fun collectRecursively(currentModel: UtModel, allModels: MutableSet, modelTagName: String? = null) { + val cgModel = with(context) { currentModel.wrap(if(currentModel.isMockModel()) modelTagName else null) } if (!allModels.add(cgModel)) { return } @@ -124,7 +124,9 @@ class SpringTestClassModelBuilder(val context: CgContext): TestClassModelBuilder // Here we traverse fields only. // Traversing mocks as well will result in wrong models playing // a role of class fields with @Mock annotation. - currentModel.fields.values.forEach { collectRecursively(it, allModels) } + currentModel.fields.forEach { (key, value) -> + collectRecursively(value, allModels, key.name) + } } is UtAssembleModel -> { currentModel.origin?.let { collectRecursively(it, allModels) } diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgAbstractSpringTestClassConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgAbstractSpringTestClassConstructor.kt index e497d835ef..c56c1ec0bf 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgAbstractSpringTestClassConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgAbstractSpringTestClassConstructor.kt @@ -21,7 +21,6 @@ import org.utbot.framework.plugin.api.UtSpringContextModel import org.utbot.framework.plugin.api.util.SpringModelUtils.getBeanNameOrNull import org.utbot.framework.plugin.api.util.id import java.lang.Exception -import java.util.Collections.max abstract class CgAbstractSpringTestClassConstructor(context: CgContext) : CgAbstractTestClassConstructor(context) { @@ -125,10 +124,8 @@ abstract class CgAbstractSpringTestClassConstructor(context: CgContext) : modelWrappers .forEach { modelWrapper -> - modelWrapper.let { - valueByUtModelWrapper[modelWrapper] = createdVariable - variableConstructor.annotatedModelGroups.getOrPut(annotationClassId) { mutableSetOf() } += modelWrapper - } + valueByUtModelWrapper[modelWrapper] = createdVariable + variableConstructor.annotatedModelGroups.getOrPut(annotationClassId) { mutableSetOf() } += modelWrapper } } diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgClassFieldManager.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgClassFieldManager.kt index 7056e5ea20..18364faf4f 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgClassFieldManager.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgClassFieldManager.kt @@ -14,7 +14,7 @@ import org.utbot.framework.plugin.api.UtModel import org.utbot.framework.plugin.api.isMockModel import org.utbot.framework.plugin.api.util.SpringModelUtils.autowiredClassId import org.utbot.framework.plugin.api.util.SpringModelUtils.isAutowiredFromContext -import java.util.* +import java.util.Collections.max import kotlin.collections.HashMap sealed interface CgClassFieldManager : CgContextOwner { @@ -92,7 +92,7 @@ class CgMockedFieldsManager(context: CgContext) : CgClassFieldManagerImpl(contex .groupByTo(HashMap()) { Pair(it.testSetId, it.executionId) } // maximal instances of one type amount in one execution - val instanceMaxCount = Collections.max(modelsByExecutions.map { (_, modelsList) -> modelsList.size }) + val instanceMaxCount = max(modelsByExecutions.map { (_, modelsList) -> modelsList.size }) // if [instanceCount] is 1, then we mock variable by @Mock annotation // Otherwise we will mock variable by simple mock later From 94278d545d0563a657380613f86f0a74cac3529b Mon Sep 17 00:00:00 2001 From: Kirill Shishin Date: Fri, 21 Jul 2023 19:35:55 +0300 Subject: [PATCH 2/5] Add tests for two cases: 1) the Engine reproduces two models on two @Autowired variables of the same type, 2) the Engine reproduces one model on two @Autowired variables of the same type --- .../twoAndMoreBeansForOneType/Person.java | 2 +- .../PersonService.java | 11 +++ .../SpringNoConfigUtValueTestCaseChecker.kt | 2 +- ...iceWithInjectedAndNonInjectedFieldTests.kt | 1 + .../ServiceWithInjectedFieldTests.kt | 1 + .../PersonServiceTest.kt | 98 +++++++++++++++++++ .../utbot/examples/spring/utils/CallUtils.kt | 18 +++- 7 files changed, 130 insertions(+), 3 deletions(-) rename utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/{oneBeanForOneType => }/SpringNoConfigUtValueTestCaseChecker.kt (87%) create mode 100644 utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonServiceTest.kt diff --git a/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/Person.java b/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/Person.java index 11522fcac4..cfd70d5bd2 100644 --- a/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/Person.java +++ b/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/Person.java @@ -16,7 +16,7 @@ public Integer getAge(){ return age; } - public String name() { + public String getName() { return firstName + " " + lastName; } } \ No newline at end of file diff --git a/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonService.java b/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonService.java index 91162dc0ce..d1236f56e7 100644 --- a/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonService.java +++ b/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonService.java @@ -3,6 +3,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.ArrayList; +import java.util.List; + @Service public class PersonService { @Autowired @@ -11,7 +14,15 @@ public class PersonService { @Autowired private Person personTwo; + public List baseOrders = new ArrayList<>(); + + // a method for testing the case when the Engine reproduces one model on @Autowired variables of the same type public Integer ageSum(){ return personOne.getAge() + personTwo.getAge(); } + + // a method for testing the case when the Engine reproduces two models on @Autowired variables of the same type + public String joinInfo(){ + return personOne.getName() + personTwo.getAge() + baseOrders.size(); + } } \ No newline at end of file diff --git a/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/oneBeanForOneType/SpringNoConfigUtValueTestCaseChecker.kt b/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/SpringNoConfigUtValueTestCaseChecker.kt similarity index 87% rename from utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/oneBeanForOneType/SpringNoConfigUtValueTestCaseChecker.kt rename to utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/SpringNoConfigUtValueTestCaseChecker.kt index 3e0e66241b..ed54103277 100644 --- a/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/oneBeanForOneType/SpringNoConfigUtValueTestCaseChecker.kt +++ b/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/SpringNoConfigUtValueTestCaseChecker.kt @@ -1,4 +1,4 @@ -package org.utbot.examples.spring.autowiring.oneBeanForOneType +package org.utbot.examples.spring.autowiring import org.utbot.examples.spring.utils.standardSpringTestingConfigurations import org.utbot.testing.UtValueTestCaseChecker diff --git a/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/oneBeanForOneType/ServiceWithInjectedAndNonInjectedFieldTests.kt b/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/oneBeanForOneType/ServiceWithInjectedAndNonInjectedFieldTests.kt index ad94545d4b..f86ddf9101 100644 --- a/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/oneBeanForOneType/ServiceWithInjectedAndNonInjectedFieldTests.kt +++ b/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/oneBeanForOneType/ServiceWithInjectedAndNonInjectedFieldTests.kt @@ -1,6 +1,7 @@ package org.utbot.examples.spring.autowiring.oneBeanForOneType import org.junit.jupiter.api.Test +import org.utbot.examples.spring.autowiring.SpringNoConfigUtValueTestCaseChecker import org.utbot.examples.spring.utils.findAllRepositoryCall import org.utbot.examples.spring.utils.springAdditionalDependencies import org.utbot.examples.spring.utils.springMockStrategy diff --git a/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/oneBeanForOneType/ServiceWithInjectedFieldTests.kt b/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/oneBeanForOneType/ServiceWithInjectedFieldTests.kt index b051d491f6..c123d7f2bd 100644 --- a/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/oneBeanForOneType/ServiceWithInjectedFieldTests.kt +++ b/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/oneBeanForOneType/ServiceWithInjectedFieldTests.kt @@ -1,6 +1,7 @@ package org.utbot.examples.spring.autowiring.oneBeanForOneType import org.junit.jupiter.api.Test +import org.utbot.examples.spring.autowiring.SpringNoConfigUtValueTestCaseChecker import org.utbot.examples.spring.utils.findAllRepositoryCall import org.utbot.examples.spring.utils.saveRepositoryCall import org.utbot.examples.spring.utils.springAdditionalDependencies diff --git a/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonServiceTest.kt b/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonServiceTest.kt new file mode 100644 index 0000000000..daa0e782e1 --- /dev/null +++ b/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonServiceTest.kt @@ -0,0 +1,98 @@ +package org.utbot.examples.spring.autowiring.twoAndMoreBeansForOneType + +import org.junit.jupiter.api.Test +import org.utbot.examples.spring.autowiring.SpringNoConfigUtValueTestCaseChecker +import org.utbot.examples.spring.utils.namePersonCall +import org.utbot.examples.spring.utils.agePersonCall +import org.utbot.examples.spring.utils.springAdditionalDependencies +import org.utbot.examples.spring.utils.springMockStrategy +import org.utbot.framework.plugin.api.UtConcreteValue +import org.utbot.testcheckers.eq +import org.utbot.testing.* + +class PersonServiceTest : SpringNoConfigUtValueTestCaseChecker( + testClass = PersonService::class, +) { + + + /** + * In this test, we check the case when the Engine reproduces two models on two @Autowired variables of the same type. + * + * Therefore, we mock all the variables and get the only necessary `mock.values` in each variable + */ + @Test + fun testJoin() { + checkThisMocksAndExceptions( + method = PersonService::joinInfo, + branches = eq(2), + { thisInstance, mocks, r -> + val personOne = mocks.singleMock("personOne", namePersonCall) + val personTwo = mocks.singleMock("personTwo", agePersonCall) + + val personOneName = personOne.value() + val personTwoAge = personTwo.value().toString() + + personOneName + personTwoAge + thisInstance.baseOrders.size == r.getOrNull() + }, + { thisInstance, mocks, r -> + val personOne = mocks.singleMock("personOne", namePersonCall) + val personTwo = mocks.singleMock("personTwo", agePersonCall) + + //Test conditions + val r1 = (personOne != null) + val r2 = (personTwo != null) + val r3 = thisInstance.baseOrders == null + + r1 && r2 && r3 && r.isException() + }, + coverage = DoNotCalculate, + mockStrategy = springMockStrategy, + additionalDependencies = springAdditionalDependencies, + ) + } + + + /** + * In this test, we check the case when the Engine reproduces one model on two @Autowired variables of the same type. + * + * Therefore, we only mock one of the variables and get all `mock.values` in it + */ + @Test + fun testAgeSum(){ + checkThisMocksAndExceptions( + method = PersonService::ageSum, + branches = ignoreExecutionsNumber, + { _, mocks, r -> + val personOne = mocks.singleMock("personOne", agePersonCall) + + val personOneAge = (personOne.values[0] as? UtConcreteValue<*>)?.value + val isPersonOneAgeNull = personOneAge == null + + isPersonOneAgeNull && r.isException() + }, + { _, mocks, r -> + val personOne = mocks.singleMock("personOne", agePersonCall) + + val personOneAge = (personOne.values[0] as? UtConcreteValue<*>)?.value + val personTwoAge = (personOne.values[1] as? UtConcreteValue<*>)?.value + + val isPersonOneAgeNull = personOneAge != null + val isPersonTwoAgeNotNull = personTwoAge == null + + isPersonOneAgeNull && isPersonTwoAgeNotNull && r.isException() + }, + { _, mocks, r -> + val personOne = mocks.singleMock("personOne", agePersonCall) + + val personOneAge = (personOne.values[0] as? UtConcreteValue<*>)?.value.toString().toInt() + val personTwoAge = (personOne.values[1] as? UtConcreteValue<*>)?.value.toString().toInt() + + personOneAge + personTwoAge == r.getOrNull() + }, + coverage = DoNotCalculate, + mockStrategy = springMockStrategy, + additionalDependencies = springAdditionalDependencies, + ) + } + +} \ No newline at end of file diff --git a/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/utils/CallUtils.kt b/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/utils/CallUtils.kt index 98ee4e02cf..86cb0648e4 100644 --- a/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/utils/CallUtils.kt +++ b/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/utils/CallUtils.kt @@ -2,6 +2,7 @@ package org.utbot.examples.spring.utils import org.utbot.examples.spring.autowiring.OrderRepository import org.utbot.examples.spring.autowiring.oneBeanForOneType.Order +import org.utbot.examples.spring.autowiring.twoAndMoreBeansForOneType.Person import kotlin.reflect.KFunction1 import kotlin.reflect.KFunction2 import kotlin.reflect.full.functions @@ -19,4 +20,19 @@ val saveRepositoryCall: KFunction2 = OrderRepository::class .functions .single { it.name == "save" && it.parameters.size == 2 } - as KFunction2 \ No newline at end of file + as KFunction2 + + +@Suppress("UNCHECKED_CAST") +val namePersonCall: KFunction1 = + Person::class + .functions + .single { it.name == "getName" && it.parameters.size == 1 } + as KFunction1 + +@Suppress("UNCHECKED_CAST") +val agePersonCall: KFunction1 = + Person::class + .functions + .single { it.name == "getAge" && it.parameters.size == 1 } + as KFunction1 \ No newline at end of file From f89cedfcae02f510cda5fc2087e7d3d24b508fcb Mon Sep 17 00:00:00 2001 From: Kirill Shishin Date: Mon, 24 Jul 2023 11:08:43 +0300 Subject: [PATCH 3/5] Some fixes --- .../CgAbstractSpringTestClassConstructor.kt | 14 ++++++- .../twoAndMoreBeansForOneType/Person.java | 9 ++++- .../PersonConfig.java | 4 +- .../PersonService.java | 6 +-- .../PersonServiceTest.kt | 40 +++++++++++-------- .../utbot/examples/spring/utils/CallUtils.kt | 6 +-- 6 files changed, 52 insertions(+), 27 deletions(-) diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgAbstractSpringTestClassConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgAbstractSpringTestClassConstructor.kt index c56c1ec0bf..35101d5054 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgAbstractSpringTestClassConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgAbstractSpringTestClassConstructor.kt @@ -1,5 +1,6 @@ package org.utbot.framework.codegen.tree +import org.utbot.framework.codegen.domain.UtModelWrapper import org.utbot.framework.codegen.domain.builtin.TestClassUtilMethodProvider import org.utbot.framework.codegen.domain.context.CgContext import org.utbot.framework.codegen.domain.models.AnnotationTarget.* @@ -124,8 +125,17 @@ abstract class CgAbstractSpringTestClassConstructor(context: CgContext) : modelWrappers .forEach { modelWrapper -> - valueByUtModelWrapper[modelWrapper] = createdVariable - variableConstructor.annotatedModelGroups.getOrPut(annotationClassId) { mutableSetOf() } += modelWrapper + val modelWrapperWithEmptyTagName = UtModelWrapper( + testSetId = modelWrapper.testSetId, + executionId = modelWrapper.executionId, + model = modelWrapper.model, + modelTagName = null, + ) + + valueByUtModelWrapper[modelWrapperWithEmptyTagName] = createdVariable + + variableConstructor.annotatedModelGroups + .getOrPut(annotationClassId) { mutableSetOf() } += modelWrapperWithEmptyTagName } } diff --git a/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/Person.java b/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/Person.java index cfd70d5bd2..df7947c55f 100644 --- a/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/Person.java +++ b/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/Person.java @@ -6,10 +6,13 @@ public class Person { private Integer age; - public Person(String firstName, String secondName, Integer age) { + private Integer weight; + + public Person(String firstName, String secondName, Integer age, Integer weight) { this.firstName = firstName; this.lastName = secondName; this.age = age; + this.weight = weight; } public Integer getAge(){ @@ -19,4 +22,8 @@ public Integer getAge(){ public String getName() { return firstName + " " + lastName; } + + public Integer getWeight() { + return weight; + } } \ No newline at end of file diff --git a/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonConfig.java b/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonConfig.java index 78f2faf0c1..408f2714dc 100644 --- a/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonConfig.java +++ b/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonConfig.java @@ -7,11 +7,11 @@ public class PersonConfig { @Bean public Person personOne() { - return new Person("Eg", "or", 7); + return new Person("Eg", "or", 7, 5); } @Bean public Person personTwo() { - return new Person("Kir", "ill", 6); + return new Person("Kir", "ill", 6, 5); } } diff --git a/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonService.java b/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonService.java index d1236f56e7..aa797f68d3 100644 --- a/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonService.java +++ b/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonService.java @@ -14,7 +14,7 @@ public class PersonService { @Autowired private Person personTwo; - public List baseOrders = new ArrayList<>(); + public final List baseOrders = new ArrayList<>(); // a method for testing the case when the Engine reproduces one model on @Autowired variables of the same type public Integer ageSum(){ @@ -22,7 +22,7 @@ public Integer ageSum(){ } // a method for testing the case when the Engine reproduces two models on @Autowired variables of the same type - public String joinInfo(){ - return personOne.getName() + personTwo.getAge() + baseOrders.size(); + public Integer joinInfo(){ + return personOne.getWeight() + personTwo.getAge() + baseOrders.size(); } } \ No newline at end of file diff --git a/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonServiceTest.kt b/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonServiceTest.kt index daa0e782e1..06584af733 100644 --- a/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonServiceTest.kt +++ b/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonServiceTest.kt @@ -2,10 +2,7 @@ package org.utbot.examples.spring.autowiring.twoAndMoreBeansForOneType import org.junit.jupiter.api.Test import org.utbot.examples.spring.autowiring.SpringNoConfigUtValueTestCaseChecker -import org.utbot.examples.spring.utils.namePersonCall -import org.utbot.examples.spring.utils.agePersonCall -import org.utbot.examples.spring.utils.springAdditionalDependencies -import org.utbot.examples.spring.utils.springMockStrategy +import org.utbot.examples.spring.utils.* import org.utbot.framework.plugin.api.UtConcreteValue import org.utbot.testcheckers.eq import org.utbot.testing.* @@ -24,26 +21,37 @@ class PersonServiceTest : SpringNoConfigUtValueTestCaseChecker( fun testJoin() { checkThisMocksAndExceptions( method = PersonService::joinInfo, - branches = eq(2), - { thisInstance, mocks, r -> - val personOne = mocks.singleMock("personOne", namePersonCall) + branches = eq(3), + { _, mocks, r -> + val personOne = mocks.singleMock("personOne", weightPersonCall) + + val personOneWeight = personOne.value() + + val r1 = personOneWeight == null + + r1 && r.isException() + }, + { _, mocks, r -> + val personOne = mocks.singleMock("personOne", weightPersonCall) val personTwo = mocks.singleMock("personTwo", agePersonCall) - val personOneName = personOne.value() - val personTwoAge = personTwo.value().toString() + val personOneWeight = personOne.value() + val personTwoAge = personTwo.value() + + val r1 = personOneWeight != null + val r2 = personTwoAge == null - personOneName + personTwoAge + thisInstance.baseOrders.size == r.getOrNull() + r1 && r2 && r.isException() }, { thisInstance, mocks, r -> - val personOne = mocks.singleMock("personOne", namePersonCall) + val personOne = mocks.singleMock("personOne", weightPersonCall) val personTwo = mocks.singleMock("personTwo", agePersonCall) - //Test conditions - val r1 = (personOne != null) - val r2 = (personTwo != null) - val r3 = thisInstance.baseOrders == null + val personOneWeight = personOne.value()!! + val personTwoAge = personTwo.value()!! + val baseOrders = thisInstance.baseOrders!! - r1 && r2 && r3 && r.isException() + personOneWeight + personTwoAge + baseOrders.size == r.getOrNull() }, coverage = DoNotCalculate, mockStrategy = springMockStrategy, diff --git a/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/utils/CallUtils.kt b/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/utils/CallUtils.kt index 86cb0648e4..e1353d0a55 100644 --- a/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/utils/CallUtils.kt +++ b/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/utils/CallUtils.kt @@ -24,11 +24,11 @@ val saveRepositoryCall: KFunction2 = @Suppress("UNCHECKED_CAST") -val namePersonCall: KFunction1 = +val weightPersonCall: KFunction1 = Person::class .functions - .single { it.name == "getName" && it.parameters.size == 1 } - as KFunction1 + .single { it.name == "getWeight" && it.parameters.size == 1 } + as KFunction1 @Suppress("UNCHECKED_CAST") val agePersonCall: KFunction1 = From 89a84004a0578466bfe4772190a1b33bd4c3f5af Mon Sep 17 00:00:00 2001 From: Kirill Shishin Date: Mon, 24 Jul 2023 15:24:05 +0300 Subject: [PATCH 4/5] Small refactoring --- .../builders/SpringTestClassModelBuilder.kt | 78 ++++++++++--------- .../CgAbstractSpringTestClassConstructor.kt | 7 +- .../twoAndMoreBeansForOneType/Person.java | 11 +-- .../PersonConfig.java | 17 ---- ...e.java => ServiceOfBeansWithSameType.java} | 6 +- ...t.kt => ServiceOfBeansWithSameTypeTest.kt} | 23 +++--- 6 files changed, 60 insertions(+), 82 deletions(-) delete mode 100644 utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonConfig.java rename utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/{PersonService.java => ServiceOfBeansWithSameType.java} (69%) rename utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/{PersonServiceTest.kt => ServiceOfBeansWithSameTypeTest.kt} (85%) diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/models/builders/SpringTestClassModelBuilder.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/models/builders/SpringTestClassModelBuilder.kt index a2036a61ca..76da5b7899 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/models/builders/SpringTestClassModelBuilder.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/domain/models/builders/SpringTestClassModelBuilder.kt @@ -83,7 +83,10 @@ class SpringTestClassModelBuilder(val context: CgContext): TestClassModelBuilder private fun collectByModel(model: UtModel): Set { val dependentModels = mutableSetOf() - collectRecursively(model, dependentModels) + + with(context){ + collectRecursively(model.wrap(), dependentModels) + } return dependentModels } @@ -98,51 +101,54 @@ class SpringTestClassModelBuilder(val context: CgContext): TestClassModelBuilder return classModels } - private fun collectRecursively(currentModel: UtModel, allModels: MutableSet, modelTagName: String? = null) { - val cgModel = with(context) { currentModel.wrap(if(currentModel.isMockModel()) modelTagName else null) } - if (!allModels.add(cgModel)) { + private fun collectRecursively(currentModelWrapper: UtModelWrapper, allModels: MutableSet) { + if (!allModels.add(currentModelWrapper)) { return } - when (currentModel) { - is UtNullModel, - is UtPrimitiveModel, - is UtClassRefModel, - is UtVoidModel, - is UtEnumConstantModel, - is UtSpringContextModel -> {} - is UtLambdaModel -> { - currentModel.capturedValues.forEach { collectRecursively(it, allModels) } - } - is UtArrayModel -> { - currentModel.stores.values.forEach { collectRecursively(it, allModels) } - if (currentModel.stores.count() < currentModel.length) { - collectRecursively(currentModel.constModel, allModels) + with(context) { + when (val currentModel = currentModelWrapper.model) { + is UtNullModel, + is UtPrimitiveModel, + is UtClassRefModel, + is UtVoidModel, + is UtEnumConstantModel, + is UtSpringContextModel -> {} + is UtLambdaModel -> { + currentModel.capturedValues.forEach { collectRecursively(it.wrap(), allModels) } } - } - is UtCompositeModel -> { - // Here we traverse fields only. - // Traversing mocks as well will result in wrong models playing - // a role of class fields with @Mock annotation. - currentModel.fields.forEach { (key, value) -> - collectRecursively(value, allModels, key.name) + is UtArrayModel -> { + currentModel.stores.values.forEach { collectRecursively(it.wrap(), allModels) } + if (currentModel.stores.count() < currentModel.length) { + collectRecursively(currentModel.constModel.wrap(), allModels) + } } - } - is UtAssembleModel -> { - currentModel.origin?.let { collectRecursively(it, allModels) } + is UtCompositeModel -> { + // Here we traverse fields only. + // Traversing mocks as well will result in wrong models playing + // a role of class fields with @Mock annotation. + currentModel.fields.forEach { (fieldId, model) -> + // We use `modelTagName` in order to distinguish mock models + val modeTagName = if(model.isMockModel()) fieldId.name else null + collectRecursively(model.wrap(modeTagName), allModels) + } + } + is UtAssembleModel -> { + currentModel.origin?.let { collectRecursively(it.wrap(), allModels) } - currentModel.instantiationCall.instance?.let { collectRecursively(it, allModels) } - currentModel.instantiationCall.params.forEach { collectRecursively(it, allModels) } + currentModel.instantiationCall.instance?.let { collectRecursively(it.wrap(), allModels) } + currentModel.instantiationCall.params.forEach { collectRecursively(it.wrap(), allModels) } - currentModel.modificationsChain.forEach { stmt -> - stmt.instance?.let { collectRecursively(it, allModels) } - when (stmt) { - is UtStatementCallModel -> stmt.params.forEach { collectRecursively(it, allModels) } - is UtDirectSetFieldModel -> collectRecursively(stmt.fieldModel, allModels) + currentModel.modificationsChain.forEach { stmt -> + stmt.instance?.let { collectRecursively(it.wrap(), allModels) } + when (stmt) { + is UtStatementCallModel -> stmt.params.forEach { collectRecursively(it.wrap(), allModels) } + is UtDirectSetFieldModel -> collectRecursively(stmt.fieldModel.wrap(), allModels) + } } } + //Python, JavaScript, Go models are not required in Spring } - //Python, JavaScript, Go models are not required in Spring } } } \ No newline at end of file diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgAbstractSpringTestClassConstructor.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgAbstractSpringTestClassConstructor.kt index 35101d5054..81ce6e6feb 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgAbstractSpringTestClassConstructor.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgAbstractSpringTestClassConstructor.kt @@ -125,17 +125,18 @@ abstract class CgAbstractSpringTestClassConstructor(context: CgContext) : modelWrappers .forEach { modelWrapper -> - val modelWrapperWithEmptyTagName = UtModelWrapper( + + val modelWrapperWithNullTagName = UtModelWrapper( testSetId = modelWrapper.testSetId, executionId = modelWrapper.executionId, model = modelWrapper.model, modelTagName = null, ) - valueByUtModelWrapper[modelWrapperWithEmptyTagName] = createdVariable + valueByUtModelWrapper[modelWrapperWithNullTagName] = createdVariable variableConstructor.annotatedModelGroups - .getOrPut(annotationClassId) { mutableSetOf() } += modelWrapperWithEmptyTagName + .getOrPut(annotationClassId) { mutableSetOf() } += modelWrapperWithNullTagName } } diff --git a/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/Person.java b/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/Person.java index df7947c55f..16cafc8cce 100644 --- a/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/Person.java +++ b/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/Person.java @@ -1,16 +1,11 @@ package org.utbot.examples.spring.autowiring.twoAndMoreBeansForOneType; public class Person { - private String firstName; - private String lastName; - private Integer age; private Integer weight; - public Person(String firstName, String secondName, Integer age, Integer weight) { - this.firstName = firstName; - this.lastName = secondName; + public Person(Integer age, Integer weight) { this.age = age; this.weight = weight; } @@ -19,10 +14,6 @@ public Integer getAge(){ return age; } - public String getName() { - return firstName + " " + lastName; - } - public Integer getWeight() { return weight; } diff --git a/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonConfig.java b/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonConfig.java deleted file mode 100644 index 408f2714dc..0000000000 --- a/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonConfig.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.utbot.examples.spring.autowiring.twoAndMoreBeansForOneType; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration -public class PersonConfig { - @Bean - public Person personOne() { - return new Person("Eg", "or", 7, 5); - } - - @Bean - public Person personTwo() { - return new Person("Kir", "ill", 6, 5); - } -} diff --git a/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonService.java b/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/ServiceOfBeansWithSameType.java similarity index 69% rename from utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonService.java rename to utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/ServiceOfBeansWithSameType.java index aa797f68d3..fe6e844b9c 100644 --- a/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonService.java +++ b/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/ServiceOfBeansWithSameType.java @@ -7,7 +7,7 @@ import java.util.List; @Service -public class PersonService { +public class ServiceOfBeansWithSameType { @Autowired private Person personOne; @@ -16,12 +16,12 @@ public class PersonService { public final List baseOrders = new ArrayList<>(); - // a method for testing the case when the Engine reproduces one model on @Autowired variables of the same type + // a method for testing the case when the Engine produces one model on @Autowired variables of the same type public Integer ageSum(){ return personOne.getAge() + personTwo.getAge(); } - // a method for testing the case when the Engine reproduces two models on @Autowired variables of the same type + // a method for testing the case when the Engine produces two models on @Autowired variables of the same type public Integer joinInfo(){ return personOne.getWeight() + personTwo.getAge() + baseOrders.size(); } diff --git a/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonServiceTest.kt b/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/ServiceOfBeansWithSameTypeTest.kt similarity index 85% rename from utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonServiceTest.kt rename to utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/ServiceOfBeansWithSameTypeTest.kt index 06584af733..cbceef42ff 100644 --- a/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/PersonServiceTest.kt +++ b/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/ServiceOfBeansWithSameTypeTest.kt @@ -7,11 +7,10 @@ import org.utbot.framework.plugin.api.UtConcreteValue import org.utbot.testcheckers.eq import org.utbot.testing.* -class PersonServiceTest : SpringNoConfigUtValueTestCaseChecker( - testClass = PersonService::class, +class ServiceOfBeansWithSameTypeTest : SpringNoConfigUtValueTestCaseChecker( + testClass = ServiceOfBeansWithSameType::class, ) { - /** * In this test, we check the case when the Engine reproduces two models on two @Autowired variables of the same type. * @@ -20,16 +19,16 @@ class PersonServiceTest : SpringNoConfigUtValueTestCaseChecker( @Test fun testJoin() { checkThisMocksAndExceptions( - method = PersonService::joinInfo, + method = ServiceOfBeansWithSameType::joinInfo, branches = eq(3), { _, mocks, r -> val personOne = mocks.singleMock("personOne", weightPersonCall) val personOneWeight = personOne.value() - val r1 = personOneWeight == null + val isPersonOneWeightNull = personOneWeight == null - r1 && r.isException() + isPersonOneWeightNull && r.isException() }, { _, mocks, r -> val personOne = mocks.singleMock("personOne", weightPersonCall) @@ -38,10 +37,10 @@ class PersonServiceTest : SpringNoConfigUtValueTestCaseChecker( val personOneWeight = personOne.value() val personTwoAge = personTwo.value() - val r1 = personOneWeight != null - val r2 = personTwoAge == null + val isPersonOneWeightNotNull = personOneWeight != null + val isPersonTwoAgeNull = personTwoAge == null - r1 && r2 && r.isException() + isPersonOneWeightNotNull && isPersonTwoAgeNull && r.isException() }, { thisInstance, mocks, r -> val personOne = mocks.singleMock("personOne", weightPersonCall) @@ -59,7 +58,6 @@ class PersonServiceTest : SpringNoConfigUtValueTestCaseChecker( ) } - /** * In this test, we check the case when the Engine reproduces one model on two @Autowired variables of the same type. * @@ -68,7 +66,7 @@ class PersonServiceTest : SpringNoConfigUtValueTestCaseChecker( @Test fun testAgeSum(){ checkThisMocksAndExceptions( - method = PersonService::ageSum, + method = ServiceOfBeansWithSameType::ageSum, branches = ignoreExecutionsNumber, { _, mocks, r -> val personOne = mocks.singleMock("personOne", agePersonCall) @@ -102,5 +100,4 @@ class PersonServiceTest : SpringNoConfigUtValueTestCaseChecker( additionalDependencies = springAdditionalDependencies, ) } - -} \ No newline at end of file +} From a99a6d093e3fe86b927109ef46424816538d6ea5 Mon Sep 17 00:00:00 2001 From: Kirill Shishin Date: Tue, 25 Jul 2023 13:53:17 +0300 Subject: [PATCH 5/5] Fix test with two models of the same type --- .../codegen/tree/CgClassFieldManager.kt | 11 ++- .../twoAndMoreBeansForOneType/Person.java | 18 ++-- .../ServiceOfBeansWithSameType.java | 4 +- .../ServiceOfBeansWithSameTypeTest.kt | 95 +++++++++++++------ .../utbot/examples/spring/utils/CallUtils.kt | 6 +- 5 files changed, 89 insertions(+), 45 deletions(-) diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgClassFieldManager.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgClassFieldManager.kt index 18364faf4f..15ffbc387b 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgClassFieldManager.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgClassFieldManager.kt @@ -88,15 +88,16 @@ class CgMockedFieldsManager(context: CgContext) : CgClassFieldManagerImpl(contex override fun fieldWithAnnotationIsRequired(modelWrappers: Set): Boolean { // group [listOfUtModels] by `testSetId` and `executionId` // to check how many instances of one type are used in each execution - val modelsByExecutions = modelWrappers + val modelWrappersByExecutions = modelWrappers .groupByTo(HashMap()) { Pair(it.testSetId, it.executionId) } - // maximal instances of one type amount in one execution - val instanceMaxCount = max(modelsByExecutions.map { (_, modelsList) -> modelsList.size }) + // maximal count of instances of the same type amount in one execution + // we use `modelTagName` in order to distinguish mock models by their name + val maxCountOfInstancesOfTheSameTypeByExecution = max(modelWrappersByExecutions.map { (_, modelsList) -> modelsList.size }) - // if [instanceCount] is 1, then we mock variable by @Mock annotation + // if [maxCountOfInstancesOfTheSameTypeByExecution] is 1, then we mock variable by @Mock annotation // Otherwise we will mock variable by simple mock later - return instanceMaxCount == 1 + return maxCountOfInstancesOfTheSameTypeByExecution == 1 } } diff --git a/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/Person.java b/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/Person.java index 16cafc8cce..64c9cb9d91 100644 --- a/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/Person.java +++ b/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/Person.java @@ -1,20 +1,22 @@ package org.utbot.examples.spring.autowiring.twoAndMoreBeansForOneType; public class Person { - private Integer age; + private String firstName; + private String lastName; - private Integer weight; + private Integer age; - public Person(Integer age, Integer weight) { + public Person(String firstName, String secondName, Integer age) { + this.firstName = firstName; + this.lastName = secondName; this.age = age; - this.weight = weight; } - public Integer getAge(){ - return age; + public String getName() { + return firstName + " " + lastName; } - public Integer getWeight() { - return weight; + public Integer getAge(){ + return age; } } \ No newline at end of file diff --git a/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/ServiceOfBeansWithSameType.java b/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/ServiceOfBeansWithSameType.java index fe6e844b9c..bf4f045e80 100644 --- a/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/ServiceOfBeansWithSameType.java +++ b/utbot-spring-sample/src/main/java/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/ServiceOfBeansWithSameType.java @@ -22,7 +22,7 @@ public Integer ageSum(){ } // a method for testing the case when the Engine produces two models on @Autowired variables of the same type - public Integer joinInfo(){ - return personOne.getWeight() + personTwo.getAge() + baseOrders.size(); + public Boolean checker() { + return personOne.getName().equals("k") && personTwo.getName().length() > 5 && baseOrders.isEmpty(); } } \ No newline at end of file diff --git a/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/ServiceOfBeansWithSameTypeTest.kt b/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/ServiceOfBeansWithSameTypeTest.kt index cbceef42ff..d57d546470 100644 --- a/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/ServiceOfBeansWithSameTypeTest.kt +++ b/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/autowiring/twoAndMoreBeansForOneType/ServiceOfBeansWithSameTypeTest.kt @@ -12,45 +12,86 @@ class ServiceOfBeansWithSameTypeTest : SpringNoConfigUtValueTestCaseChecker( ) { /** - * In this test, we check the case when the Engine reproduces two models on two @Autowired variables of the same type. + * In this test, we check the case when the Engine produces two models on two @Autowired variables of the same type. * - * Therefore, we mock all the variables and get the only necessary `mock.values` in each variable + * The engine produce two models only in the tests, when `baseOrder` is a testing participant. + * In these tests, we mock all the variables and get the only necessary `mock.values` in each variable. */ @Test - fun testJoin() { + fun testChecker() { checkThisMocksAndExceptions( - method = ServiceOfBeansWithSameType::joinInfo, - branches = eq(3), - { _, mocks, r -> - val personOne = mocks.singleMock("personOne", weightPersonCall) + method = ServiceOfBeansWithSameType::checker, + branches = eq(6), + {_, mocks, r -> + val personOne = mocks.singleMock("personOne", namePersonCall) - val personOneWeight = personOne.value() + val personOneName = personOne.value() - val isPersonOneWeightNull = personOneWeight == null + val r1 = personOneName == null - isPersonOneWeightNull && r.isException() + r1 && r.isException() }, - { _, mocks, r -> - val personOne = mocks.singleMock("personOne", weightPersonCall) - val personTwo = mocks.singleMock("personTwo", agePersonCall) + {_, mocks, r -> + val person = mocks.singleMock("personOne", namePersonCall) + + val personOneName = (person.values[0] as? UtConcreteValue<*>)?.value + val personTwoName = (person.values[1] as? UtConcreteValue<*>)?.value + + val r1 = personOneName == "k" + val r2 = personTwoName == null - val personOneWeight = personOne.value() - val personTwoAge = personTwo.value() + r1 && r2 && r.isException() + }, + {_, mocks, r -> + val personOne = mocks.singleMock("personOne", namePersonCall) + + val personOneName = personOne.value() - val isPersonOneWeightNotNull = personOneWeight != null - val isPersonTwoAgeNull = personTwoAge == null + val r1 = personOneName != "k" - isPersonOneWeightNotNull && isPersonTwoAgeNull && r.isException() + r1 && (r.getOrNull() == false) }, - { thisInstance, mocks, r -> - val personOne = mocks.singleMock("personOne", weightPersonCall) - val personTwo = mocks.singleMock("personTwo", agePersonCall) + {_, mocks, r -> + val person = mocks.singleMock("personOne", namePersonCall) + + val personOneName = (person.values[0] as? UtConcreteValue<*>)?.value + val personTwoName = (person.values[1] as? UtConcreteValue<*>)?.value.toString() - val personOneWeight = personOne.value()!! - val personTwoAge = personTwo.value()!! - val baseOrders = thisInstance.baseOrders!! + val r1 = personOneName == "k" + val r2 = personTwoName.length <= 5 - personOneWeight + personTwoAge + baseOrders.size == r.getOrNull() + r1 && r2 && (r.getOrNull() == false) + }, + + //In this test Engine produces two models on two @Autowired variables of the same type + {thisInstance, mocks, r -> + val personOne = mocks.singleMock("personOne", namePersonCall) + val personTwo = mocks.singleMock("personTwo", namePersonCall) + + val personOneName = (personOne.values[0] as? UtConcreteValue<*>)?.value + val personTwoName = (personTwo.values[0] as? UtConcreteValue<*>)?.value.toString() + val baseOrders = thisInstance.baseOrders + + val r1 = personOneName == "k" + val r2 = personTwoName.length > 5 + val r3 = baseOrders.isEmpty() + + r1 && r2 && r3 && (r.getOrNull() == true) + }, + + {thisInstance, mocks, r -> + val personOne = mocks.singleMock("personOne", namePersonCall) + val personTwo = mocks.singleMock("personTwo", namePersonCall) + + val personOneName = (personOne.values[0] as? UtConcreteValue<*>)?.value + val personTwoName = (personTwo.values[0] as? UtConcreteValue<*>)?.value.toString() + val baseOrders = thisInstance.baseOrders + + val r1 = personOneName == "k" + val r2 = personTwoName.length > 5 + val r3 = baseOrders.isNotEmpty() + + r1 && r2 && r3 && (r.getOrNull() == false) }, coverage = DoNotCalculate, mockStrategy = springMockStrategy, @@ -59,7 +100,7 @@ class ServiceOfBeansWithSameTypeTest : SpringNoConfigUtValueTestCaseChecker( } /** - * In this test, we check the case when the Engine reproduces one model on two @Autowired variables of the same type. + * In this test, we check the case when the Engine produces one model on two @Autowired variables of the same type. * * Therefore, we only mock one of the variables and get all `mock.values` in it */ @@ -67,7 +108,7 @@ class ServiceOfBeansWithSameTypeTest : SpringNoConfigUtValueTestCaseChecker( fun testAgeSum(){ checkThisMocksAndExceptions( method = ServiceOfBeansWithSameType::ageSum, - branches = ignoreExecutionsNumber, + branches = eq(3), { _, mocks, r -> val personOne = mocks.singleMock("personOne", agePersonCall) diff --git a/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/utils/CallUtils.kt b/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/utils/CallUtils.kt index e1353d0a55..86cb0648e4 100644 --- a/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/utils/CallUtils.kt +++ b/utbot-spring-test/src/test/kotlin/org/utbot/examples/spring/utils/CallUtils.kt @@ -24,11 +24,11 @@ val saveRepositoryCall: KFunction2 = @Suppress("UNCHECKED_CAST") -val weightPersonCall: KFunction1 = +val namePersonCall: KFunction1 = Person::class .functions - .single { it.name == "getWeight" && it.parameters.size == 1 } - as KFunction1 + .single { it.name == "getName" && it.parameters.size == 1 } + as KFunction1 @Suppress("UNCHECKED_CAST") val agePersonCall: KFunction1 =