diff --git a/utbot-framework-test/src/test/kotlin/org/utbot/examples/mock/MockStaticFieldExampleTest.kt b/utbot-framework-test/src/test/kotlin/org/utbot/examples/mock/MockStaticFieldExampleTest.kt index 18bdabb472..27bbea1d8b 100644 --- a/utbot-framework-test/src/test/kotlin/org/utbot/examples/mock/MockStaticFieldExampleTest.kt +++ b/utbot-framework-test/src/test/kotlin/org/utbot/examples/mock/MockStaticFieldExampleTest.kt @@ -6,15 +6,29 @@ import org.utbot.framework.plugin.api.MockInfo import org.utbot.framework.plugin.api.MockStrategyApi.OTHER_PACKAGES import kotlin.reflect.KClass import org.junit.jupiter.api.Test +import org.utbot.examples.mock.others.ClassWithStaticField +import org.utbot.framework.plugin.api.CodegenLanguage +import org.utbot.framework.plugin.api.UtCompositeModel +import org.utbot.framework.plugin.api.UtNewInstanceInstrumentation import org.utbot.testcheckers.eq import org.utbot.testcheckers.withoutConcrete +import org.utbot.testing.CodeGeneration import org.utbot.testing.DoNotCalculate +import org.utbot.testing.TestExecution import org.utbot.testing.UtValueTestCaseChecker import org.utbot.testing.singleMock import org.utbot.testing.singleMockOrNull import org.utbot.testing.value -internal class MockStaticFieldExampleTest : UtValueTestCaseChecker(testClass = MockStaticFieldExample::class) { +internal class MockStaticFieldExampleTest : UtValueTestCaseChecker( + testClass = MockStaticFieldExample::class, + testCodeGeneration = true, + pipelines = listOf( + TestLastStage(CodegenLanguage.JAVA, lastStage = TestExecution), + // disabled due to https://github.com/UnitTestBot/UTBotJava/issues/88 + TestLastStage(CodegenLanguage.KOTLIN, lastStage = CodeGeneration) + ) +) { @Test fun testMockStaticField() { @@ -68,6 +82,42 @@ internal class MockStaticFieldExampleTest : UtValueTestCaseChecker(testClass = M } } + @Test + fun testCheckMocksInLeftAndRightAssignPartFinalField() { + checkMocks( + MockStaticFieldExample::checkMocksInLeftAndRightAssignPartFinalField, + eq(1), + { mocks, _ -> + val mock = mocks.singleMock("staticFinalField", ClassWithStaticField::foo) + + mock.mocksStaticField(MockStaticFieldExample::class) + }, + coverage = DoNotCalculate, + mockStrategy = OTHER_PACKAGES + ) + } + + @Test + fun testCheckMocksInLeftAndRightAssignPart() { + checkMocksAndInstrumentation( + MockStaticFieldExample::checkMocksInLeftAndRightAssignPart, + eq(2), + { _, statics, _ -> + val instrumentation = statics.single() as UtNewInstanceInstrumentation + val model = instrumentation.instances.last() as UtCompositeModel + + model.fields.isEmpty() // NPE + }, + { mocks, _, _ -> + val mock = mocks.singleMock("staticField", ClassWithStaticField::foo) + + mock.mocksStaticField(MockStaticFieldExample::class) + }, + coverage = DoNotCalculate, + mockStrategy = OTHER_PACKAGES + ) + } + private fun MockInfo.mocksStaticField(kClass: KClass<*>) = when (val mock = mock) { is FieldMockTarget -> mock.ownerClassName == kClass.qualifiedName && mock.owner == null else -> false diff --git a/utbot-framework/src/main/kotlin/org/utbot/engine/Traverser.kt b/utbot-framework/src/main/kotlin/org/utbot/engine/Traverser.kt index 3f7beb7f3c..0a5bcee5bb 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/engine/Traverser.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/engine/Traverser.kt @@ -1910,10 +1910,10 @@ class Traverser( with(simplificator) { simplifySymbolicValue(it) } } - private fun readStaticField(fieldRef: StaticFieldRef): SymbolicValue { + private fun TraversalContext.readStaticField(fieldRef: StaticFieldRef): SymbolicValue { val field = fieldRef.field val declaringClassType = field.declaringClass.type - val staticObject = findOrCreateStaticObject(declaringClassType) + val staticObject = resolveInstanceForField(fieldRef) val generator = (field.type as? RefType)?.let { refType -> UtMockInfoGenerator { mockAddr -> @@ -3592,7 +3592,12 @@ class Traverser( staticFieldsUpdates.removeAll { update -> update.fieldId == it.fieldId } fieldValuesUpdates.keys.removeAll { key -> key.fieldId == it.fieldId } - val value = createConst(it.type, it.name) + val generator = UtMockInfoGenerator { mockAddr -> + val fieldId = FieldId(it.declaringClass.id, it.name) + UtFieldMockInfo(it.type.classId, mockAddr, fieldId, ownerAddr = null) + } + + val value = createConst(it.type, it.name, generator) val valueToStore = if (value is ReferenceValue) { value.addr } else { diff --git a/utbot-sample/src/main/java/org/utbot/examples/mock/MockStaticFieldExample.java b/utbot-sample/src/main/java/org/utbot/examples/mock/MockStaticFieldExample.java index 916f6a2759..4de83e353f 100644 --- a/utbot-sample/src/main/java/org/utbot/examples/mock/MockStaticFieldExample.java +++ b/utbot-sample/src/main/java/org/utbot/examples/mock/MockStaticFieldExample.java @@ -1,5 +1,6 @@ package org.utbot.examples.mock; +import org.utbot.examples.mock.others.ClassWithStaticField; import org.utbot.examples.mock.others.Generator; public class MockStaticFieldExample { @@ -7,6 +8,9 @@ public class MockStaticFieldExample { private static Generator privateGenerator; public static Generator publicGenerator; + public static final ClassWithStaticField staticFinalField = new ClassWithStaticField(); + public static ClassWithStaticField staticField = new ClassWithStaticField(); + public int calculate(int threshold) { int a = privateGenerator.generateInt(); int b = publicGenerator.generateInt(); @@ -15,4 +19,20 @@ public int calculate(int threshold) { } return a + b + 1; } + + // This test is associated with https://github.com/UnitTestBot/UTBotJava/issues/1533 + public int checkMocksInLeftAndRightAssignPartFinalField() { + staticFinalField.intField = 5; + staticFinalField.anotherIntField = staticFinalField.foo(); + + return staticFinalField.anotherIntField; + } + + // This test is associated with https://github.com/UnitTestBot/UTBotJava/issues/1533 + public int checkMocksInLeftAndRightAssignPart() { + staticField.intField = 5; + staticField.anotherIntField = staticField.foo(); + + return staticField.anotherIntField; + } } \ No newline at end of file diff --git a/utbot-sample/src/main/java/org/utbot/examples/mock/others/ClassWithStaticField.java b/utbot-sample/src/main/java/org/utbot/examples/mock/others/ClassWithStaticField.java new file mode 100644 index 0000000000..fb6d8bbb06 --- /dev/null +++ b/utbot-sample/src/main/java/org/utbot/examples/mock/others/ClassWithStaticField.java @@ -0,0 +1,10 @@ +package org.utbot.examples.mock.others; + +public class ClassWithStaticField { + public int intField; + public int anotherIntField; + + public int foo() { + return 5; + } +}