UnitTestBot / UTBotJava

Automated unit test generation and precise code analysis for Java
Apache License 2.0
136 stars 43 forks source link

Mockito dependency needed by tests, but not added by plugin #2740

Open liblit-at-amazon opened 7 months ago

liblit-at-amazon commented 7 months ago

Description

UnitTestBot generates a test suite that uses several Mockito API components. However, no suitable Mockito dependency is present or is added by the plugin.

To Reproduce

Steps to reproduce the behavior:

  1. Check out https://github.com/atn-lyn/lyn-parents. For the issue reported here, the current master head revision of this repository was atn-lyn/lyn-parents@3ff5ce71555d04418e0911cfc75b8c702905c722, but it is not clear whether this issue is sensitive to this specific revision.

  2. Add the following to pom.xml to explicitly select Java 1.8:

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
  3. Open this project in IntelliJ IDEA and link its pom.xml, thereby making this a Maven project.

  4. In the IntelliJ IDEA Project Settings, select a Java 1.8 SDK.

  5. If this import line in lyn-web/src/main/java/com/lyn/web/controller/GoodsController.java fails to resolve in the IDE, then delete it.

  6. Use the UnitTestBot IntelliJ IDEA plugin to generate tests for the com.lyn.web.controller.GoodsController.search(String, Pageable) method. Leave all UnitTestBot settings at their defaults, other than selecting this one method to generate tests for.

Expected behavior

UnitTestBot should have generated one or more tests that are ready to compile and run in the IDE.

Actual behavior

UnitTestBot generated a test class with multiple test methods:

Generated `GoodsControllerTest.java` ```java package com.lyn.web.controller; import com.lyn.common.cache.CacheService; import com.lyn.goods.api.service.GoodsService; import com.lyn.web.elastic.GoodsEsRepository; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.TermQueryBuilder; import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockedConstruction; import org.mockito.MockedConstruction.Context; import org.mockito.MockedStatic; import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.kafka.core.KafkaTemplate; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.*; import static org.mockito.MockitoAnnotations.openMocks; public final class GoodsControllerTest { @InjectMocks private GoodsController goodsController; @Mock private KafkaTemplate kafkaTemplateMock; @Mock private CacheService cacheServiceMock; @Mock private GoodsEsRepository goodsEsRepositoryMock; @Mock private GoodsService goodsServiceMock; private AutoCloseable mockitoCloseable; ///region Test suites for executable com.lyn.web.controller.GoodsController.search ///region SYMBOLIC EXECUTION: ERROR SUITE for method search(java.lang.String, org.springframework.data.domain.Pageable) /** * @utbot.classUnderTest {@link GoodsController} * @utbot.methodUnderTest {@link GoodsController#search(String, Pageable)} * @utbot.invokes {@link QueryBuilders#boolQuery()} * @utbot.invokes {@link QueryBuilders#termQuery(String, int)} * @utbot.invokes {@link BoolQueryBuilder#filter(org.elasticsearch.index.query.QueryBuilder)} * @utbot.throwsException {@link NullPointerException} in: boolBuilder.filter(QueryBuilders.termQuery("status", 1)); */ @Test public void testSearch_ThrowNullPointerException() throws Exception { MockedConstruction mockedConstruction = null; MockedStatic mockedStatic = null; try { mockedConstruction = mockConstruction(NativeSearchQueryBuilder.class, (NativeSearchQueryBuilder nativeSearchQueryBuilderMock, Context context) -> { }); mockedStatic = mockStatic(QueryBuilders.class); (mockedStatic.when(QueryBuilders::boolQuery)).thenReturn(((BoolQueryBuilder) null)); (mockedStatic.when(() -> QueryBuilders.termQuery(any(String.class), anyInt()))).thenReturn(((TermQueryBuilder) null)); /* This test fails because method [com.lyn.web.controller.GoodsController.search] produces [java.lang.NullPointerException] */ goodsController.search(null, null); } finally { mockedConstruction.close(); mockedStatic.close(); } } ///endregion ///region FUZZER: SECURITY for method search(java.lang.String, org.springframework.data.domain.Pageable) /** * @utbot.classUnderTest {@link GoodsController} * @utbot.methodUnderTest {@link GoodsController#search(String, Pageable)} */ @Test(expected = ExceptionInInitializerError.class) @Ignore(value = "Disabled due to sandbox") public void testSearchWithNonEmptyString() throws Exception { Pageable pagMock = mock(Pageable.class); goodsController.search("#\"$\\'", pagMock); } ///endregion ///region FUZZER: ERROR SUITE for method search(java.lang.String, org.springframework.data.domain.Pageable) /** * @utbot.classUnderTest {@link GoodsController} * @utbot.methodUnderTest {@link GoodsController#search(String, Pageable)} */ @Test(expected = NoClassDefFoundError.class) public void testSearchThrowsNCDFEWithNonEmptyString() throws Exception { Pageable pagMock = mock(Pageable.class); goodsController.search("#$\\\"'", pagMock); } ///endregion ///endregion @Before public void setUp() { mockitoCloseable = openMocks(this); } @After public void tearDown() throws Exception { mockitoCloseable.close(); } } ```

However, this test class fails to compile and run in IntelliJ IDEA. Attempting to do so produces the following compilation errors:

/path/to/project/lyn-parents/lyn-web/utbot_tests/com/lyn/web/controller/GoodsControllerTest.java:15:19
java: cannot find symbol
  symbol:   class MockedConstruction
  location: package org.mockito
/path/to/project/lyn-parents/lyn-web/utbot_tests/com/lyn/web/controller/GoodsControllerTest.java:16:38
java: package org.mockito.MockedConstruction does not exist
/path/to/project/lyn-parents/lyn-web/utbot_tests/com/lyn/web/controller/GoodsControllerTest.java:17:19
java: cannot find symbol
  symbol:   class MockedStatic
  location: package org.mockito
/path/to/project/lyn-parents/lyn-web/utbot_tests/com/lyn/web/controller/GoodsControllerTest.java:25
java: cannot find symbol
  symbol:   static openMocks
  location: class
/path/to/project/lyn-parents/lyn-web/utbot_tests/com/lyn/web/controller/GoodsControllerTest.java:59:9
java: cannot find symbol
  symbol:   class MockedConstruction
  location: class com.lyn.web.controller.GoodsControllerTest
/path/to/project/lyn-parents/lyn-web/utbot_tests/com/lyn/web/controller/GoodsControllerTest.java:60:9
java: cannot find symbol
  symbol:   class MockedStatic
  location: class com.lyn.web.controller.GoodsControllerTest
/path/to/project/lyn-parents/lyn-web/utbot_tests/com/lyn/web/controller/GoodsControllerTest.java:62:34
java: cannot find symbol
  symbol:   method mockConstruction(java.lang.Class<org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder>,(NativeSea[...]->{ })
  location: class com.lyn.web.controller.GoodsControllerTest
/path/to/project/lyn-parents/lyn-web/utbot_tests/com/lyn/web/controller/GoodsControllerTest.java:62:139
java: cannot find symbol
  symbol:   class Context
  location: class com.lyn.web.controller.GoodsControllerTest
/path/to/project/lyn-parents/lyn-web/utbot_tests/com/lyn/web/controller/GoodsControllerTest.java:64:28
java: cannot find symbol
  symbol:   method mockStatic(java.lang.Class<org.elasticsearch.index.query.QueryBuilders>)
  location: class com.lyn.web.controller.GoodsControllerTest
/path/to/project/lyn-parents/lyn-web/utbot_tests/com/lyn/web/controller/GoodsControllerTest.java:111:28
java: cannot find symbol
  symbol:   method openMocks(com.lyn.web.controller.GoodsControllerTest)
  location: class com.lyn.web.controller.GoodsControllerTest

The UnitTestBot IDE plugin already modifies pom.xml files to add JUnit dependencies as needed. It should add a suitable Mockito dependency as well.

Environment