Skip to content

Commit efe2b62

Browse files
committed
Fix review comments
1 parent fb0d081 commit efe2b62

File tree

3 files changed

+56
-40
lines changed

3 files changed

+56
-40
lines changed

utbot-framework-test/src/test/kotlin/org/utbot/examples/mock/CommonMocksExampleTest.kt

+9-7
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,21 @@ package org.utbot.examples.mock
33
import org.utbot.framework.plugin.api.MockStrategyApi
44
import org.junit.jupiter.api.Test
55
import org.utbot.testcheckers.eq
6-
import org.utbot.testing.DoNotCalculate
76
import org.utbot.testing.UtValueTestCaseChecker
7+
import org.utbot.testing.atLeast
88

99
internal class CommonMocksExampleTest: UtValueTestCaseChecker(testClass = CommonMocksExample::class) {
1010

11+
//TODO: coverage values here require further investigation by experts
12+
1113
@Test
1214
fun testMockInterfaceWithoutImplementorsWithNoMocksStrategy() {
1315
checkMocks(
1416
CommonMocksExample::mockInterfaceWithoutImplementors,
1517
eq(1),
1618
{ v, mocks, _ -> v == null && mocks.isEmpty() },
17-
coverage = DoNotCalculate,
1819
mockStrategy = MockStrategyApi.NO_MOCKS,
20+
coverage = atLeast(75),
1921
)
2022
}
2123

@@ -26,8 +28,8 @@ internal class CommonMocksExampleTest: UtValueTestCaseChecker(testClass = Common
2628
eq(2),
2729
{ v, mocks, _ -> v == null && mocks.isEmpty() },
2830
{ _, mocks, _ -> mocks.singleOrNull() != null },
29-
coverage = DoNotCalculate,
3031
mockStrategy = MockStrategyApi.OTHER_CLASSES,
32+
coverage = atLeast(75),
3133
)
3234
}
3335

@@ -40,7 +42,7 @@ internal class CommonMocksExampleTest: UtValueTestCaseChecker(testClass = Common
4042
{ fst, _, mocks, _ -> fst == null && mocks.isEmpty() },
4143
{ _, _, mocks, _ -> mocks.isEmpty() }, // should be changed to not null fst when 1449 will be finished
4244
mockStrategy = MockStrategyApi.OTHER_PACKAGES,
43-
coverage = DoNotCalculate
45+
coverage = atLeast(75)
4446
)
4547
}
4648

@@ -55,7 +57,7 @@ internal class CommonMocksExampleTest: UtValueTestCaseChecker(testClass = Common
5557
// node == node.next
5658
// node.next.value == node.value + 1
5759
mockStrategy = MockStrategyApi.OTHER_CLASSES,
58-
coverage = DoNotCalculate
60+
coverage = atLeast(13)
5961
)
6062
}
6163

@@ -66,7 +68,7 @@ internal class CommonMocksExampleTest: UtValueTestCaseChecker(testClass = Common
6668
eq(1),
6769
{ r -> r == -420 },
6870
mockStrategy = MockStrategyApi.OTHER_CLASSES,
69-
coverage = DoNotCalculate
71+
coverage = atLeast(70),
7072
)
7173
}
7274

@@ -76,7 +78,7 @@ internal class CommonMocksExampleTest: UtValueTestCaseChecker(testClass = Common
7678
CommonMocksExample::mocksForNullOfDifferentTypes,
7779
eq(1),
7880
mockStrategy = MockStrategyApi.OTHER_PACKAGES,
79-
coverage = DoNotCalculate
81+
coverage = atLeast(75)
8082
)
8183
}
8284
}

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

+31-31
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ data class UtStaticMethodMockInfo(
130130
) : UtMockInfo(methodId.classId, addr)
131131

132132
/**
133-
* A wrapper for [ObjectValue] to store additional onfo.
133+
* A wrapper for [ObjectValue] to store additional info.
134134
*/
135135
sealed class MockedObjectInfo {
136136
abstract val value: ObjectValue?
@@ -142,16 +142,18 @@ object NoMock: MockedObjectInfo() {
142142

143143
/**
144144
* Represents a mock that occurs when mock strategy allows it
145-
* or when an object type is in a set that requires force mocking.
145+
* or when an object type requires always requires mocking.
146+
*
147+
* See [Mocker.mockAlways] for more details.
146148
*/
147149
class ExpectedMock(objectValue: ObjectValue): MockedObjectInfo() {
148150
override val value: ObjectValue = objectValue
149151
}
150152

151153
/**
152-
* Represents a mock that occurs when it is not recommended
154+
* Represents a mock that occurs when it is not allowed.
153155
* E.g. mock framework is not installed or
154-
* mock startegy is DO_NOT_MOCK and class is not in mockAlways set.
156+
* mock strategy is [MockStrategy.NO_MOCKS] and class is not in [Mocker.mockAlways] set.
155157
*/
156158
class UnexpectedMock(objectValue: ObjectValue): MockedObjectInfo() {
157159
override val value: ObjectValue = objectValue
@@ -170,31 +172,6 @@ class Mocker(
170172
) {
171173
private val mocksAreDesired: Boolean = strategy != MockStrategy.NO_MOCKS
172174

173-
/**
174-
* Constructs [MockedObjectInfo]: enriches given value with
175-
* an information if this mock is expected or not.
176-
*/
177-
fun construct(value: ObjectValue?, mockInfo: UtMockInfo): MockedObjectInfo {
178-
if (value == null) {
179-
return NoMock
180-
}
181-
182-
val mockingIsPossible = when (mockInfo) {
183-
is UtFieldMockInfo,
184-
is UtObjectMockInfo -> applicationContext.mockFrameworkInstalled
185-
is UtNewInstanceMockInfo,
186-
is UtStaticMethodMockInfo,
187-
is UtStaticObjectMockInfo -> applicationContext.staticsMockingIsConfigured
188-
}
189-
val mockingIsForcedAndPossible = mockAlways(value.type) && mockingIsPossible
190-
191-
return if (mocksAreDesired || mockingIsForcedAndPossible) {
192-
ExpectedMock(value)
193-
} else {
194-
UnexpectedMock(value)
195-
}
196-
}
197-
198175
/**
199176
* Creates mocked instance (if it should be mocked by the mocker) of the [type] using [mockInfo]
200177
* otherwise returns [NoMock].
@@ -207,8 +184,7 @@ class Mocker(
207184
}
208185

209186
/**
210-
* Creates mocked instance of the [type] using [mockInfo]
211-
* it does not check anything and always returns the constructed mock.
187+
* Unlike to [mock], unconditionally creates a mocked instance of the [type] using [mockInfo].
212188
*/
213189
fun forceMock(type: RefType, mockInfo: UtMockInfo): MockedObjectInfo {
214190
mockListenerController?.onShouldMock(strategy, mockInfo)
@@ -241,6 +217,30 @@ class Mocker(
241217
}
242218
}
243219

220+
/**
221+
* Constructs [MockedObjectInfo]: enriches given [mockedValue] with an information if mocking is expected or not.
222+
*/
223+
private fun construct(mockedValue: ObjectValue?, mockInfo: UtMockInfo): MockedObjectInfo {
224+
if (mockedValue == null) {
225+
return NoMock
226+
}
227+
228+
val mockingIsPossible = when (mockInfo) {
229+
is UtFieldMockInfo,
230+
is UtObjectMockInfo -> applicationContext.mockFrameworkInstalled
231+
is UtNewInstanceMockInfo,
232+
is UtStaticMethodMockInfo,
233+
is UtStaticObjectMockInfo -> applicationContext.staticsMockingIsConfigured
234+
}
235+
val mockingIsForcedAndPossible = mockAlways(mockedValue.type) && mockingIsPossible
236+
237+
return if (mocksAreDesired || mockingIsForcedAndPossible) {
238+
ExpectedMock(mockedValue)
239+
} else {
240+
UnexpectedMock(mockedValue)
241+
}
242+
}
243+
244244
private fun checkIfShouldMock(
245245
type: RefType,
246246
mockInfo: UtMockInfo

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

+16-2
Original file line numberDiff line numberDiff line change
@@ -1382,14 +1382,15 @@ class Traverser(
13821382

13831383
val mockedObjectInfo = mocker.mock(type, mockInfo)
13841384

1385-
val mockedObject = mockedObjectInfo.value
13861385
if (mockedObjectInfo is UnexpectedMock) {
13871386
// if mock occurs, but it is unexpected due to some reasons
13881387
// (e.g. we do not have mock framework installed),
13891388
// we can only generate a test that uses null value for mocked object
13901389
queuedSymbolicStateUpdates += nullEqualityConstraint.asHardConstraint()
1390+
return mockedObjectInfo.value
13911391
}
13921392

1393+
val mockedObject = mockedObjectInfo.value
13931394
if (mockedObject != null) {
13941395
queuedSymbolicStateUpdates += MemoryUpdate(mockInfos = persistentListOf(MockInfoEnriched(mockInfo)))
13951396

@@ -1478,7 +1479,7 @@ class Traverser(
14781479
val mockedObjectInfo = mocker.forceMock(type, mockInfoGenerator.generate(addr))
14791480

14801481
val mockedObject: ObjectValue = when (mockedObjectInfo) {
1481-
is NoMock -> error("Value must be mocked after the fore mock")
1482+
is NoMock -> error("Value must be mocked after the force mock")
14821483
is ExpectedMock -> mockedObjectInfo.value
14831484
is UnexpectedMock -> {
14841485
// if mock occurs, but it is unexpected due to some reasons
@@ -1490,6 +1491,10 @@ class Traverser(
14901491
}
14911492
}
14921493

1494+
if (mockedObjectInfo is UnexpectedMock) {
1495+
return mockedObject
1496+
}
1497+
14931498
queuedSymbolicStateUpdates += MemoryUpdate(mockInfos = persistentListOf(MockInfoEnriched(mockInfo)))
14941499

14951500
// add typeConstraint for mocked object. It's a declared type of the object.
@@ -2728,6 +2733,15 @@ class Traverser(
27282733
// TODO isMock????
27292734
InvocationTarget(mockedObject, method, constraints)
27302735
}
2736+
/*
2737+
Currently, it is unclear how this could happen.
2738+
Perhaps, the answer is somewhere in the following situation:
2739+
you have an interface with an abstract method `foo`, and it has an abstract inheritor with the implementation of the method,
2740+
but this inheritor doesn't have any concrete inheritors. It looks like in this case we would mock this instance
2741+
(because it doesn't have any possible concrete type), but it is impossible since either this class cannot present
2742+
in possible types of the object on which we call `foo` (since they contain only concrete types),
2743+
or this class would be already mocked (since it doesn't contain any concrete implementors).
2744+
*/
27312745
is UnexpectedMock -> unreachableBranch("If it ever happens, it should be investigated")
27322746
}
27332747
}

0 commit comments

Comments
 (0)