簡體   English   中英

如何修復此錯誤:java.lang.NoSuchMethodError: 'java.lang.AutoCloseable org.mockito.MockitoAnnotations.openMocks(java.lang.Object)'

[英]How to fix this error: java.lang.NoSuchMethodError: 'java.lang.AutoCloseable org.mockito.MockitoAnnotations.openMocks(java.lang.Object)'

所以我在我的 Spring 啟動 Gradle 項目中遇到了這個錯誤:

'java.lang.AutoCloseable org.mockito.MockitoAnnotations.openMocks(java.lang.Object)'
    java.lang.NoSuchMethodError: 'java.lang.AutoCloseable org.mockito.MockitoAnnotations.openMocks(java.lang.Object)'

我似乎無法修復它。 我已經搜索了答案,但我得到的唯一一個是從您的依賴項中刪除 mockito-all,但我的 gradle.build 文件中首先沒有這個。

我的 build.gradle 文件:

plugins {
    id 'org.springframework.boot' version '2.4.2'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
    id "org.sonarqube" version "3.0"
    id 'jacoco'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '15'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}


dependencies {
    compile 'org.apache.httpcomponents:httpcore:4.4.1'
    compile 'org.apache.httpcomponents:httpclient:4.5'
    implementation('io.jsonwebtoken:jjwt:0.2')
    implementation 'org.springframework.boot:spring-boot-starter-mail'
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compile 'junit:junit:4.12'
    implementation 'org.modelmapper:modelmapper:2.4.1'
    compileOnly 'org.projectlombok:lombok'
    runtimeOnly 'mysql:mysql-connector-java'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    implementation 'org.eclipse.jgit:org.eclipse.jgit:5.4.2.201908231537-r'
    /**
     * JUnit jupiter with mockito.
     */
    testCompile group: 'org.mockito', name: 'mockito-junit-jupiter', version: '2.19.0'

    testCompile group: 'org.mockito', name: 'mockito-core', version: '2.19.0'
    testCompile group: 'org.springframework.security', name: 'spring-security-test', version: '5.1.6.RELEASE'
}

sonarqube{
    properties{
        property 'sonarjava.source', '1.8'
        property 'sonar.java.coveragePlugin', 'jacoco'
        property 'sonar.jacoco.reportPaths', 'build/reports/jacoco/test/jacocoTestReport.xml'
    }
}
test {
    useJUnitPlatform()
}

我似乎找不到解決方案,所以我來到了這里,也許一些代碼大神可以幫助我解決我的問題。

我收到此錯誤的文件是測試 class:

測試 class:

package com.example.demo.Service;

import com.example.demo.DTO.PartyLeaderDto;
import com.example.demo.Model.PartyLeader;
import com.example.demo.Repository.PartyLeaderRepository;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import static org.mockito.Mockito.verify;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.modelmapper.ModelMapper;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Optional;

import static org.mockito.Mockito.when;
import static org.mockito.ArgumentMatchers.argThat;

@SpringBootTest
@AutoConfigureMockMvc
public class PartyLeaderServiceMockTest {
    @Rule
    public MockitoRule initRule = MockitoJUnit.rule();

    @Mock
    private PartyLeaderRepository partyLeaderRepository;

    @Mock
    private ModelMapper modelMapper;

    @InjectMocks
    private PartyLeaderService partyLeaderService; // this is like calling new PartyLeaderService(partyLeaderRepository, modelMapper);


    @Test
    void whenSavePartyLeader_thenCorrectPartyLeaderSaved() {
        // given
        var input = PartyLeaderDto.builder()
                .name("Josse")
                .apperance("Link of image")
                .build();

        // when
        partyLeaderService.savePartyLeader(input);


        // then
        verify(partyLeaderRepository).save(argThat(entity ->
                entity.getName().equals("Josse")
                        && entity.getApperance().equals("Link of image")));
    }


    @Test
    void whenGetPartyLeader_ShouldReturnCorrectLeaderData() {
        // given
        var partyLeaderEntity = PartyLeader.builder()
                .name("Josse")
                .apperance("Link of image")
                .build();
        var partyLeaderDto = PartyLeaderDto.builder()
                .name("Josse")
                .apperance("Link of image")
                .build();
        when(partyLeaderRepository.findById(3)).thenReturn(Optional.of(partyLeaderEntity));
        when(modelMapper.map(partyLeaderEntity, PartyLeaderDto.class)).thenReturn(partyLeaderDto);

        // when
        var result = partyLeaderService.getPartyLeader(3);

        // then
        Assert.assertEquals(result, partyLeaderDto);
    }
}

我在兩個測試中都遇到了同樣的錯誤。

誰能幫我? 提前致謝!

問題是由於 jar 沖突引起的

我們需要排除

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit</groupId>
                <artifactId>junit</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.mockito</groupId>
                <artifactId>mockito-core</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.mockito</groupId>
                <artifactId>mockito-all</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

並包括

<dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <version>3.11.2</version>
    </dependency>

對我來說,這里提到的所有解決方法都不起作用。

mockito-core3.3.3更新到3.4.3解決了這個問題。

我認為這是由於 MockitoAnnotations.initMock() 方法已被棄用並被 Mockito JUnit 5 第 3 版中的 MockitoAnnotations.openMocks() 取代。

另一方面,可能值得檢查本地 Maven 存儲庫並刪除可能導致沖突的不必要的 jars。 但是在應用此步驟時,請注意不要刪除手動安裝的(或在操作前備份)。

遇到同樣的問題后。 請查看日志跟蹤。

java.lang.NoSuchMethodError: org.mockito.MockitoAnnotations.openMocks(Ljava/lang/Object;)Ljava/lang/AutoCloseable;
    at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.initMocks(MockitoTestExecutionListener.java:83)

終於找到了解決辦法:

Mockito 版本 2中有一個MockitoAnnotations.initMock()方法,在Mockito Z8965A291ED530E8417029D中已棄用並替換為 MockitoAnnotations.openMocks() 方法。 MockitoAnnotations.openMocks()方法返回 AutoClosable 的實例,可用於在測試后關閉資源。

手動初始化

在做任何其他事情之前,我們必須添加 Mockito 依賴項。

dependencies {
    testImplementation('org.mockito:mockito-core:3.7.7')
}

MockitoAnnotations.openMocks(this) 調用告訴 Mockito 掃描此測試 class 實例以查找使用 @Mock 注釋注釋的任何字段,並將這些字段初始化為模擬。

優點:

易於創建模擬非常易讀

缺點:

不驗證框架使用或檢測不正確的存根自動模擬注入我們還可以告訴 Mockito 自動將模擬注入到帶有 @InjectMocks 注釋的字段中。

MockitoAnnotations.openMocks()被調用時,Mockito 將:

為帶有@Mock 注釋的字段創建模擬 創建一個帶有@InjectMocks 注釋的字段的實例並嘗試將模擬注入其中 使用@InjectMocks 與我們手動實例化實例時所做的相同,但現在是自動的。

public class MockitoInjectMocksTests {

    @Mock
    private OrderRepository orderRepository;
    private AutoCloseable closeable;
    @InjectMocks
    private OrderService orderService;

    @BeforeEach
    void initService() {
        closeable = MockitoAnnotations.openMocks(this);
    }

    @AfterEach
    void closeService() throws Exception {
        closeable.close();
    }

    @Test
    void createOrderSetsTheCreationDate() {
        Order order = new Order();
        when(orderRepository.save(any(Order.class))).then(returnsFirstArg());

        Order savedOrder = orderService.create(order);

        assertNotNull(savedOrder.getCreationDate());
    }
}

Mockito 將首先嘗試通過構造函數注入、setter 注入或字段注入來注入 mock。

優點:

易於注入模擬

缺點:

不強制使用構造函數注入

我遇到了同樣的問題,我通過使用 Mockito.mock() 方法而不是 @Mock 來解決它。

在我的情況下,發生錯誤是因為在 MockitoTestExecutinListener class 的 initMocks 方法中看起來像這樣:

private void initMocks(TestContext testContext) {
    if (hasMockitoAnnotations(testContext)) {
        testContext.setAttribute(MOCKS_ATTRIBUTE_NAME, MockitoAnnotations.openMocks(testContext.getTestInstance()));
    }
}

但在我的情況下,MockitoAnnotations 只有 initMocks() 方法,所以錯誤。

在這種情況下,我們需要確保 hasMockitoAnnotations(testContext) 為 false。 為了使用@Mock,我需要啟用 Mockito 注釋,但我不想要這個,因此我使用了 Mockito.mock()。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM