Skip to content

Commit 5aab381

Browse files
committed
Fix no targets for invocation for abstract this type
1 parent 31713eb commit 5aab381

File tree

3 files changed

+52
-2
lines changed

3 files changed

+52
-2
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package org.utbot.examples.objects
2+
3+
import org.junit.jupiter.api.Test
4+
import org.utbot.testcheckers.eq
5+
import org.utbot.testing.UtValueTestCaseChecker
6+
7+
class AbstractAnonymousClassTest : UtValueTestCaseChecker(testClass = AbstractAnonymousClass::class) {
8+
@Test
9+
fun testNonOverriddenMethod() {
10+
check(
11+
AbstractAnonymousClass::methodWithoutOverrides,
12+
eq(1)
13+
)
14+
}
15+
}

utbot-framework/src/main/kotlin/org/utbot/engine/Traverser.kt

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1365,7 +1365,34 @@ class Traverser(
13651365
possibleConcreteTypes
13661366
)
13671367
} else {
1368-
typeStoragePossiblyWithOverriddenTypes
1368+
val possibleTypes = typeStoragePossiblyWithOverriddenTypes.possibleConcreteTypes
1369+
val isTypeInappropriate = type.sootClass?.isInappropriate == true
1370+
1371+
// If we're trying to construct this instance and it has an inappropriate type,
1372+
// we won't be able to instantiate its instance in resulting tests.
1373+
// Therefore, we have to test one of its inheritors that does not override
1374+
// the method under test
1375+
if (addr.isThisAddr && isTypeInappropriate) {
1376+
val possibleTypesWithNonOverriddenMethod = possibleTypes
1377+
.filterTo(mutableSetOf()) {
1378+
val methods = (it as RefType).sootClass.methods
1379+
methods.none { method ->
1380+
val methodUnderTest = environment.method
1381+
val parameterTypes = method.parameterTypes
1382+
1383+
method.name == methodUnderTest.name && parameterTypes == methodUnderTest.parameterTypes
1384+
}
1385+
}
1386+
1387+
require(possibleTypesWithNonOverriddenMethod.isNotEmpty()) {
1388+
"We do not support testing for abstract classes (or interfaces) without any non-abstract " +
1389+
"inheritors (implementors). Probably, it'll be supported in the future."
1390+
}
1391+
1392+
TypeStorage.constructTypeStorageUnsafe(type, possibleTypesWithNonOverriddenMethod)
1393+
} else {
1394+
typeStoragePossiblyWithOverriddenTypes
1395+
}
13691396
}
13701397

13711398
val typeHardConstraint = typeRegistry.typeConstraint(addr, typeStorage).all().asHardConstraint()
@@ -2238,7 +2265,7 @@ class Traverser(
22382265
if (type.sootClass.isEnum) {
22392266
createEnum(type, addr)
22402267
} else {
2241-
createObject(addr, type, useConcreteType = addr.isThisAddr, mockInfoGenerator)
2268+
createObject(addr, type, useConcreteType = false, mockInfoGenerator)
22422269
}
22432270
}
22442271
is VoidType -> voidValue

utbot-sample/src/main/java/org/utbot/examples/objects/AbstractAnonymousClass.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ abstract class AbstractAnonymousClass {
44
abstract int constValue();
55
abstract int add(int x);
66

7+
public int methodWithoutOverrides(int x, int y) {
8+
return y + addFortyTwo(x);
9+
}
10+
11+
public int addFortyTwo(int x) {
12+
return x + 42;
13+
}
14+
715
public static AbstractAnonymousClass getInstance(int x) {
816
if (x % 2 == 0) {
917
return new AnonymousClassAlternative();

0 commit comments

Comments
 (0)