@@ -121,7 +121,9 @@ import org.utbot.framework.plugin.api.ClassId
121
121
import org.utbot.framework.plugin.api.ExecutableId
122
122
import org.utbot.framework.plugin.api.FieldId
123
123
import org.utbot.framework.plugin.api.MethodId
124
- import org.utbot.framework.plugin.api.SpringApplicationContext
124
+ import org.utbot.framework.plugin.api.TypeReplacementMode.AnyImplementor
125
+ import org.utbot.framework.plugin.api.TypeReplacementMode.KnownImplementor
126
+ import org.utbot.framework.plugin.api.TypeReplacementMode.NoImplementors
125
127
import org.utbot.framework.plugin.api.classId
126
128
import org.utbot.framework.plugin.api.id
127
129
import org.utbot.framework.plugin.api.util.executable
@@ -1365,7 +1367,7 @@ class Traverser(
1365
1367
traverseException(current, symException)
1366
1368
}
1367
1369
1368
- // TODO HACK violation of encapsulation
1370
+ // TODO: HACK violation of encapsulation
1369
1371
fun createObject (
1370
1372
addr : UtAddrExpression ,
1371
1373
type : RefType ,
@@ -1374,8 +1376,13 @@ class Traverser(
1374
1376
): ObjectValue {
1375
1377
touchAddress(addr)
1376
1378
1377
- val concreteClassId = applicationContext.replaceTypeIfNeeded(type)
1378
- concreteClassId?.let {
1379
+ val replacedClassId = when (applicationContext.typeReplacementMode) {
1380
+ KnownImplementor -> applicationContext.replaceTypeIfNeeded(type)
1381
+ AnyImplementor ,
1382
+ NoImplementors -> null
1383
+ }
1384
+
1385
+ replacedClassId?.let {
1379
1386
val sootType = typeResolver.classOrDefault(it.canonicalName)
1380
1387
val typeStorage = typeResolver.constructTypeStorage(sootType, useConcreteType = false )
1381
1388
@@ -1481,58 +1488,66 @@ class Traverser(
1481
1488
return it
1482
1489
}
1483
1490
1484
- // In Spring application we may rely on concrete types obtained from bean definitions only,
1485
- // and this potential replacement has already been suggested in the beginning of the method
1486
- val useConcreteTypes = applicationContext !is SpringApplicationContext
1487
-
1488
- if (useConcreteTypes && typeStorage.possibleConcreteTypes.any()) {
1489
- // If we have this$0 with UtArrayList type, we have to create such instance.
1490
- // We should create an object with typeStorage of all possible real types and concrete implementation
1491
- // Otherwise we'd have either a wrong type in the resolver, or missing method like 'preconditionCheck'.
1492
- val concreteImplementation = wrapperToClass[type]?.first()?.let { wrapper(it, addr) }?.concrete
1493
- val isMockConstraint = mkEq(typeRegistry.isMock(addr), UtFalse )
1494
-
1495
- queuedSymbolicStateUpdates + = typeHardConstraint
1496
- queuedSymbolicStateUpdates + = mkOr(isMockConstraint, nullEqualityConstraint).asHardConstraint()
1491
+ if (typeStorage.possibleConcreteTypes.isEmpty()) {
1492
+ requireNotNull(mockInfoGenerator) {
1493
+ " An object with $addr and $type doesn't have concrete possible types," +
1494
+ " but there is no mock info generator provided to construct a mock value."
1495
+ }
1497
1496
1498
- return ObjectValue (typeStorage, addr, concreteImplementation)
1499
- }
1497
+ val mockInfo = mockInfoGenerator.generate(addr)
1498
+ val mockedObjectInfo = mocker.forceMock(type, mockInfoGenerator.generate(addr))
1499
+
1500
+ val mockedObject: ObjectValue = when (mockedObjectInfo) {
1501
+ is NoMock -> error(" Value must be mocked after the force mock" )
1502
+ is ExpectedMock -> mockedObjectInfo.value
1503
+ is UnexpectedMock -> {
1504
+ // if mock occurs, but it is unexpected due to some reasons
1505
+ // (e.g. we do not have mock framework installed),
1506
+ // we can only generate a test that uses null value for mocked object
1507
+ queuedSymbolicStateUpdates + = nullEqualityConstraint.asHardConstraint()
1508
+
1509
+ mockedObjectInfo.value
1510
+ }
1511
+ }
1500
1512
1501
- requireNotNull(mockInfoGenerator) {
1502
- " An object with $addr and $type doesn't have concrete possible types," +
1503
- " but there is no mock info generator provided to construct a mock value."
1504
- }
1513
+ if (mockedObjectInfo is UnexpectedMock ) {
1514
+ return mockedObject
1515
+ }
1505
1516
1506
- val mockInfo = mockInfoGenerator.generate(addr)
1507
- val mockedObjectInfo = mocker.forceMock(type, mockInfoGenerator.generate(addr))
1517
+ queuedSymbolicStateUpdates + = MemoryUpdate (mockInfos = persistentListOf(MockInfoEnriched (mockInfo)))
1508
1518
1509
- val mockedObject: ObjectValue = when (mockedObjectInfo) {
1510
- is NoMock -> error(" Value must be mocked after the force mock" )
1511
- is ExpectedMock -> mockedObjectInfo.value
1512
- is UnexpectedMock -> {
1513
- // if mock occurs, but it is unexpected due to some reasons
1514
- // (e.g. we do not have mock framework installed),
1515
- // we can only generate a test that uses null value for mocked object
1516
- queuedSymbolicStateUpdates + = nullEqualityConstraint.asHardConstraint()
1519
+ // add typeConstraint for mocked object. It's a declared type of the object.
1520
+ val typeConstraint = typeRegistry.typeConstraint(addr, mockedObject.typeStorage).all()
1521
+ val isMockConstraint = mkEq(typeRegistry.isMock(mockedObject.addr), UtTrue )
1517
1522
1518
- mockedObjectInfo.value
1519
- }
1520
- }
1523
+ queuedSymbolicStateUpdates + = typeConstraint.asHardConstraint()
1524
+ queuedSymbolicStateUpdates + = mkOr(isMockConstraint, nullEqualityConstraint).asHardConstraint()
1521
1525
1522
- if (mockedObjectInfo is UnexpectedMock ) {
1523
1526
return mockedObject
1524
1527
}
1525
1528
1526
- queuedSymbolicStateUpdates + = MemoryUpdate (mockInfos = persistentListOf(MockInfoEnriched (mockInfo)))
1529
+ val concreteImplementation = when (applicationContext.typeReplacementMode) {
1530
+ AnyImplementor -> {
1531
+ val isMockConstraint = mkEq(typeRegistry.isMock(addr), UtFalse )
1527
1532
1528
- // add typeConstraint for mocked object. It's a declared type of the object.
1529
- val typeConstraint = typeRegistry.typeConstraint(addr, mockedObject.typeStorage).all()
1530
- val isMockConstraint = mkEq(typeRegistry.isMock(mockedObject.addr), UtTrue )
1533
+ queuedSymbolicStateUpdates + = typeHardConstraint
1534
+ queuedSymbolicStateUpdates + = mkOr(isMockConstraint, nullEqualityConstraint).asHardConstraint()
1531
1535
1532
- queuedSymbolicStateUpdates + = typeConstraint.asHardConstraint()
1533
- queuedSymbolicStateUpdates + = mkOr(isMockConstraint, nullEqualityConstraint).asHardConstraint()
1536
+ // If we have this$0 with UtArrayList type, we have to create such instance.
1537
+ // We should create an object with typeStorage of all possible real types and concrete implementation
1538
+ // Otherwise we'd have either a wrong type in the resolver, or missing method like 'preconditionCheck'.
1539
+ wrapperToClass[type]?.first()?.let { wrapper(it, addr) }?.concrete
1540
+ }
1541
+ // In case of known implementor we should have already tried to replace type using `replaceTypeIfNeeded`.
1542
+ KnownImplementor ,
1543
+ // If no implementors are allowed, we should have already generated a mock object.
1544
+ NoImplementors -> {
1545
+ queuedSymbolicStateUpdates + = mkFalse().asHardConstraint()
1546
+ null
1547
+ }
1548
+ }
1534
1549
1535
- return mockedObject
1550
+ return ObjectValue (typeStorage, addr, concreteImplementation)
1536
1551
}
1537
1552
1538
1553
0 commit comments