Title: Test generation fails for Optional
Open Graph Title: Test generation fails for Optional
X Title: Test generation fails for Optional
Description: Description No test cases are generated for methods involving Java Optional
Open Graph Description: Description No test cases are generated for methods involving Java Optional
X Description: Description No test cases are generated for methods involving Java Optional<T> class. UtErrors are generated by the engine during traverse due to ClassNotFound exception: UtOptional class can...
Opengraph URL: https://github.com/UnitTestBot/UTBotJava/issues/226
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Test generation fails for Optional\u003cT\u003e class in the plugin","articleBody":"**Description**\r\n\r\nNo test cases are generated for methods involving Java `Optional\u003cT\u003e` class. `UtError`s are generated by the engine during `traverse` due to `ClassNotFound` exception: `UtOptional` class can't be loaded. This behavior may be reproduced using the Idea plugin, but models are successfully generated for the same code in the engine unit tests.\r\n\r\n**To Reproduce**\r\n\r\nGenerate unit tests for the sample method:\r\n\r\n```\r\nimport java.util.Optional;\r\n\r\npublic class OptionalExamples {\r\n public Optional\u003cInteger\u003e nonEmptyIfPositive(int n) {\r\n if (n \u003e 0) {\r\n return Optional.of(n);\r\n } else {\r\n return Optional.empty();\r\n }\r\n }\r\n}\r\n```\r\n\r\n**Expected behavior**\r\n\r\nTwo tests are generated, one for each branch in the code (see *Additional context* for more details).\r\n\r\n**Actual behavior**\r\n\r\nErrors are reported:\r\n\r\n```\r\npublic class OptionalExamplesTest {\r\n ///region Test suites for executable collections.OptionalExamples.nonEmptyIfPositive\r\n\r\n\r\n ///region Errors report for nonEmptyIfPositive\r\n\r\n public void testNonEmptyIfPositive_errors() {\r\n // Couldn't generate some tests. List of errors:\r\n // \r\n // 2 occurrences of:\r\n // org.utbot.engine.overrides.collections.UtOptional\r\n\r\n }\r\n ///endregion\r\n\r\n ///endregion\r\n}\r\n```\r\n\r\n**Environment**\r\n\r\nMockito: any configuration. Test framework: JUnit5.\r\n\r\n**Additional context**\r\n\r\nThe primary error reason: `UtOptional` wrapper is used instead of `Optional`, but the class loader used by the test generator in the plugin can't find it. It's OK (engine-specific wrappers should never leak to the user), but `shouldMock` function checks the class and fails with `ClassNotFound` exception.\r\n\r\nAdding a check to `shouldMock` fixes the exception, but the execution path corresponding to `Optional.empty()` return value is lost unless `checkNpeForFinalFields` setting is set to `true` (it is `false` by default). See `SootField.shouldBeNotNull()` declared in `Extensions.kt`.\r\n\r\nA similar code sample that uses `OptionalInt` instead of `Optional\u003cInteger\u003e` is processed without any problems, because primitive field types are never mocked so no class check is performed.\r\n\r\nCode sample:\r\n```\r\npublic OptionalInt nonEmptyOptionalIntIfPositive(int n) {\r\n if (n \u003e 0) {\r\n return OptionalInt.of(n);\r\n } else {\r\n return OptionalInt.empty();\r\n }\r\n}\r\n```\r\n\r\nGenerated tests:\r\n```\r\n///region SUCCESSFUL EXECUTIONS for method nonEmptyOptionalIntIfPositive(int)\r\n\r\n/**\r\n * \u003cpre\u003e\r\n * Test executes conditions:\r\n * {@code (n \u003e 0): True }\r\n * invokes:\r\n * OptionalInt::of once\r\n * returns from: {@code return OptionalInt.of(n); }\r\n * \u003c/pre\u003e\r\n */\r\n@Test\r\n@DisplayName(\"nonEmptyOptionalIntIfPositive: n \u003e 0 : True -\u003e return OptionalInt.of(n)\")\r\npublic void testNonEmptyOptionalIntIfPositive_NGreaterThanZero() {\r\n OptionalExamples optionalExamples = new OptionalExamples();\r\n\r\n OptionalInt actual = optionalExamples.nonEmptyOptionalIntIfPositive(1);\r\n\r\n OptionalInt expected = of(1);\r\n\r\n assertTrue(deepEquals(expected, actual));\r\n}\r\n\r\n/**\r\n * \u003cpre\u003e\r\n * Test executes conditions:\r\n * {@code (n \u003e 0): False }\r\n * \u003c/pre\u003e\r\n */\r\n@Test\r\n@DisplayName(\"nonEmptyOptionalIntIfPositive: -\u003e n \u003e 0 : False\")\r\npublic void testNonEmptyOptionalIntIfPositive_NLessOrEqualZero() throws ClassNotFoundException, Exception {\r\n Class optionalIntClazz = Class.forName(\"java.util.OptionalInt\");\r\n OptionalInt prevEMPTY = ((OptionalInt) getStaticFieldValue(optionalIntClazz, \"EMPTY\"));\r\n try {\r\n OptionalInt empty = empty();\r\n setStaticField(optionalIntClazz, \"EMPTY\", empty);\r\n OptionalExamples optionalExamples = new OptionalExamples();\r\n\r\n OptionalInt actual = optionalExamples.nonEmptyOptionalIntIfPositive(0);\r\n\r\n\r\n assertTrue(deepEquals(empty, actual));\r\n } finally {\r\n setStaticField(OptionalInt.class, \"EMPTY\", prevEMPTY);\r\n }\r\n}\r\n///endregion\r\n```\r\n","author":{"url":"https://github.com/dtim","@type":"Person","name":"dtim"},"datePublished":"2022-06-16T15:56:09.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/226/UTBotJava/issues/226"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:9b9d2ec6-4594-53e7-0a6c-fe5b1c8a4050 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | D010:20196:11A8292:18241F1:698E213F |
| html-safe-nonce | ee3845e21c0415fbe99025aee3ac3d758dfa9466b2d74bad01c6c61ef4657748 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJEMDEwOjIwMTk2OjExQTgyOTI6MTgyNDFGMTo2OThFMjEzRiIsInZpc2l0b3JfaWQiOiIxNjg4NDI4MjM3OTgwMzExODcxIiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | f4a67afa1d3e0ca4c9517118e339dfb77662fe913eb7dbdd8b6fabeca8647d11 |
| hovercard-subject-tag | issue:1273763032 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/UnitTestBot/UTBotJava/226/issue_layout |
| twitter:image | https://opengraph.githubassets.com/5704e76f8b170f2adb4528731751dddc8181071a77b30edea93f22941b6a3464/UnitTestBot/UTBotJava/issues/226 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/5704e76f8b170f2adb4528731751dddc8181071a77b30edea93f22941b6a3464/UnitTestBot/UTBotJava/issues/226 |
| og:image:alt | Description No test cases are generated for methods involving Java Optional |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | dtim |
| hostname | github.com |
| expected-hostname | github.com |
| None | 7d71262819a4a68a7786924c05495bfd40a7561e4258dd129ba36f53d667639a |
| turbo-cache-control | no-preview |
| go-import | github.com/UnitTestBot/UTBotJava git https://github.com/UnitTestBot/UTBotJava.git |
| octolytics-dimension-user_id | 87413538 |
| octolytics-dimension-user_login | UnitTestBot |
| octolytics-dimension-repository_id | 480810501 |
| octolytics-dimension-repository_nwo | UnitTestBot/UTBotJava |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 480810501 |
| octolytics-dimension-repository_network_root_nwo | UnitTestBot/UTBotJava |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 1d904ac995eb43f93014fbdbcc9ae5878653c932 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width