无法在SpringBoot-Junit5-Mockito中模拟RestTemplate

时间:2019-02-07 18:27:43

标签: java spring-boot mockito resttemplate junit5

我正在尝试在我的DAO类中模拟其余模板,但是Mockito抛出奇怪的错误,说它无法模拟。

尝试涵盖我的Spring Boot应用程序版本2.x的单元测试用例。我几乎尝试了互联网上所有可能的解决方案,例如更新JDK / JRE进行编译,但遇到以下错误:

Option Explicit

Sub Main()
  Dim wb As Workbook
  Dim Data, Last, Mgr
  Dim i As Long, j As Long, k As Long, a As Long
  Dim Dest As Range
  Dim BASEPATH As String, strNewPath As String

  BASEPATH = "C:\Users\cuts\"

  Set wb = Workbooks("CIB_Assessment_Template.xlsx")

  Set Dest = wb.Sheets("Assessment Results").Range("B2")

  With ThisWorkbook.Sheets("Sheet1")
    Data = .Range("S2", .Range("A" & Rows.Count).End(xlUp))
  End With
  wb.Activate
  Application.ScreenUpdating = False

  For i = 1 To UBound(Data)

    If Data(i, 1) <> Last Then

      If i > 1 Then

        Dest.Select

            Last = Data(i, 1)
            Mgr = Data(i, 2)

            strNewPath = BASEPATH & Mgr & "\"
            If Len(Dir(strNewPath, vbDirectory)) = 0 Then
                MkDir strNewPath
            End If


            strNewPath = strNewPath & Last & "\"
            If Len(Dir(strNewPath, vbDirectory)) = 0 Then
                MkDir strNewPath
            End If


        wb.SaveCopyAs strNewPath & _
          "CIB_Assessment.xlsx"
      End If
      Dest.Resize(, Columns.Count - Dest.Column).EntireColumn.ClearContents
      Last = Data(i, 1)
      Mgr = Data(i, 2)
      j = 0
    End If

    a = 0
    For k = 1 To UBound(Data, 2)
      Dest.Offset(a, j) = Data(i, k)
      a = a + 1
    Next
    j = j + 1
  Next

   SaveCopy wb, Last, Mgr '<< save the last report


End Sub

以下是我的代码:

build.gradle

org.mockito.exceptions.base.MockitoException: 
Mockito cannot mock this class: class org.springframework.web.client.RestTemplate.

Mockito can only mock non-private & non-final classes.
If you're not sure why you're getting this error, please report to the mailing list.


Java               : 1.8
JVM vendor name    : Oracle Corporation
JVM vendor version : 25.181-b13
JVM name           : Java HotSpot(TM) 64-Bit Server VM
JVM version        : 1.8.0_181-b13
JVM info           : mixed mode
OS name            : Windows 10
OS version         : 10.0


Underlying exception : java.lang.IllegalArgumentException: Could not create type
    at org.mockito.junit.jupiter.MockitoExtension.beforeEach(MockitoExtension.java:115)
....

MyDao.java

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    implementation 'org.springframework.boot:spring-boot-starter-data-rest'
    implementation 'org.springframework.retry:spring-retry'
    implementation 'org.aspectj:aspectjrt'
    implementation 'org.aspectj:aspectjweaver'
    implementation 'org.springframework:spring-aop'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'

    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.2.0'
    testCompile 'org.junit.jupiter:junit-jupiter-params:5.2.0'
    testRuntime 'org.junit.jupiter:junit-jupiter-engine:5.2.0'
    testImplementation 'org.mockito:mockito-core:2.+'
    testImplementation 'org.mockito:mockito-junit-jupiter:2.18.3'
}

test {
    testLogging.showStandardStreams = true
    useJUnitPlatform()
}

MyDaoTest.java

@Repository
public class MyDao {    
    @Value("${app.prop.service.url}")
    private String url;

    @Autowired
    public RestTemplate restTemplate;

    public String getSignals() {
        System.out.println("url -----------------------> " + url);
        return new RetryTemplate().execute(context -> {
            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);

            if (response.getStatusCodeValue() == 200) {
                System.out.println("Server response -> " + response.getBody());
                return response.getBody();
            } else {
                throw new RuntimeException("server response status: " + response.getStatusCode());
            }
        }, context -> {
            System.out.println("retry count: " + context.getRetryCount());
            System.err.println("error -> " + context.getLastThrowable());
            return null;
        });
    }
}

RestTemplate的BeanConfig

@ExtendWith(MockitoExtension.class)
public class MyDaoTest {    
    @Mock
    private RestTemplate restTemplate;

    @InjectMocks
    private MyDao dao;

    @BeforeEach
    public void prepare() {
        ResponseEntity<String> response = new ResponseEntity<>("{name: myname}", HttpStatus.OK);
        Mockito.doReturn(response).when(restTemplate.getForEntity(Mockito.anyString(), String.class));
    }

    @Test
    public void testGetSignals() {
        System.out.println("------------------TEST-------------------");
        String result = dao.getSignals();
        System.out.println("result ------>" + result);
        assertEquals("{name: myname}", result);
    }
}

任何建议都会很有帮助

P.S:应用程序通过gradle命令运行正常

@Bean
public RestTemplate restTemplate() {
    // block of code for SSL config for HTTPS connection
    return new RestTemplate();
}

问题仅在于单元测试

gradlew bootRun

3 个答案:

答案 0 :(得分:1)

所描述的(或从属的)问题的一个原因可能是,由于RestTemplate既不是“私有的”也不是“最终的”,并且“已知为可模拟的”,restTemplate.getForEntity()的调用/模拟是< / p>

...在current version中,此方法可用于以下三种类型/具有重载参数:

  • ... getForEntity(String url, Class<T> responseType, Object... uriVariables) ...
  • ... getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables) ...
  • ... getForEntity(URI url, Class<T> responseType) ...

在您的(执行)代码中,您似乎使用了第一种风味,因此,在不更改(执行代码)的情况下,我建议将测试代码调整为:

...restTemplate.getForEntity(Mockito.anyString(), String.class
/*!!!*/, ArgumentMatchers.<Object>any());

另请参阅:


但是错误消息仍然让我“谨慎”并想知道...您处于“边缘” junit(5)堆栈上,您对测试设置有信心吗? (缺少gradle libs / config?)

请“尝试”:

testCompile "org.mockito:mockito-core:2.+"
testCompile('org.mockito:mockito-junit-jupiter:2.18.3')

不是:

...
testImplementation 'org.mockito:mockito-core:2.+'
testImplementation 'org.mockito:mockito-junit-jupiter:2.18.3'

..如dzone's spring-boot-2-with-junit-5-and-mockito-2-for-unit所示。 如果这样做(以及本教程中的其他发现)无济于事,请考虑采用以下方法:

  

将其报告到邮件列表(。)


(我一生中)我第一次听/读

  

模拟 DAO类中的休息模板

请考虑将您的dao命名为“服务”(以及相应的步骤/重构;)

答案 1 :(得分:0)

好的,我解决了这个问题。这是嘲笑核心和嘲笑木星罐子之间的版本不匹配,这导致了问题。

正确的依赖项是:

testImplementation 'org.junit.jupiter:junit-jupiter-api:5.2.0'
testCompile 'org.junit.jupiter:junit-jupiter-params:5.2.0'
testRuntime 'org.junit.jupiter:junit-jupiter-engine:5.2.0'
testImplementation 'org.mockito:mockito-core:2.18.3'
testImplementation 'org.mockito:mockito-junit-jupiter:2.18.3'

以前,是

testImplementation 'org.mockito:mockito-core:2.+'

Gradle选择了最新版本的模仿内核jar,因为它被要求选择2.x系列中的任何版本,如构建文件中所定义。我相信剩下的就是自我解释。

很高兴,单元测试! :P

答案 2 :(得分:0)

这个问题发生在我身上,因为我无意中运行Java11。一旦切换到该项目的标准Java 8,问题就消失了。