简体   繁体   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)'

So I am getting this error in my Spring boot Gradle project:所以我在我的 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)'

And I cannot seem to fix it.我似乎无法修复它。 I have searched for the answer but the only one I get is removing mockito-all from your dependencies, but I do not have that in my gradle.build file in the first place.我已经搜索了答案,但我得到的唯一一个是从您的依赖项中删除 mockito-all,但我的 gradle.build 文件中首先没有这个。

My build.gradle file:我的 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()
}

I can't seem to find a solution so I came to here, where some code god maybe can help me fixing my problem.我似乎找不到解决方案,所以我来到了这里,也许一些代码大神可以帮助我解决我的问题。

The file where I get this error on is a test class:我收到此错误的文件是测试 class:

The test 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);
    }
}

I get the same error on both of my tests.我在两个测试中都遇到了同样的错误。

Can anyone help me?谁能帮我? Thanks in advance!提前致谢!

Issue was due to the jar conflicts问题是由于 jar 冲突引起的

We need to exclude我们需要排除

<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>

And include并包括

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

For me, none of the workarounds mentioned here did not work.对我来说,这里提到的所有解决方法都不起作用。

Updating mockito-core from 3.3.3 to 3.4.3 fixed the problem.mockito-core3.3.3更新到3.4.3解决了这个问题。

I think it is caused by that MockitoAnnotations.initMock() method is deprecated and replaced with MockitoAnnotations.openMocks() in Mockito JUnit 5 version 3.我认为这是由于 MockitoAnnotations.initMock() 方法已被弃用并被 Mockito JUnit 5 第 3 版中的 MockitoAnnotations.openMocks() 取代。

On the other hand, it may be worthy to check the local Maven Repository and delete unnecessary jars that may cause conflict.另一方面,可能值得检查本地 Maven 存储库并删除可能导致冲突的不必要的 jars。 But when applying this step, be attention and don't delete manually installed ones (or get backup before the operation).但是在应用此步骤时,请注意不要删除手动安装的(或在操作前备份)。

After facing the same issue.遇到同样的问题后。 Please look log trace.请查看日志跟踪。

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)

Finally got a solution:终于找到了解决办法:

In Mockito version 2 there is a MockitoAnnotations.initMock() method, which is deprecated and replaced with MockitoAnnotations.openMocks() in Mockito JUnit 5 version 3 .Mockito 版本 2中有一个MockitoAnnotations.initMock()方法,在Mockito Z8965A291ED530E8417029D中已弃用并替换为 MockitoAnnotations.openMocks() 方法。 The MockitoAnnotations.openMocks() method returns an instance of AutoClosable which can be used to close the resource after the test. MockitoAnnotations.openMocks()方法返回 AutoClosable 的实例,可用于在测试后关闭资源。

Manual Initialization手动初始化

Before doing anything else, we have to add the Mockito dependency.在做任何其他事情之前,我们必须添加 Mockito 依赖项。

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

The MockitoAnnotations.openMocks(this) call tells Mockito to scan this test class instance for any fields annotated with the @Mock annotation and initialize those fields as mocks. MockitoAnnotations.openMocks(this) 调用告诉 Mockito 扫描此测试 class 实例以查找使用 @Mock 注释注释的任何字段,并将这些字段初始化为模拟。

Pros:优点:

Easy to create mocks Very readable易于创建模拟非常易读

Cons:缺点:

Does not validate framework usage or detect incorrect stubbing Automatic Mock Injection We can also tell Mockito to inject mocks automatically to a field annotated with @InjectMocks.不验证框架使用或检测不正确的存根自动模拟注入我们还可以告诉 Mockito 自动将模拟注入到带有 @InjectMocks 注释的字段中。

When MockitoAnnotations.openMocks() is called, Mockito will:MockitoAnnotations.openMocks()被调用时,Mockito 将:

Create mocks for fields annotated with the @Mock annotation Create an instance of the field annotated with @InjectMocks and try to inject the mocks into it Using @InjectMocks is the same as we did when instantiating an instance manually, but now automatic.为带有@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 will first try to inject mocks by constructor injection, followed by setter injection, or field injection. Mockito 将首先尝试通过构造函数注入、setter 注入或字段注入来注入 mock。

Pros:优点:

Easy to inject mocks易于注入模拟

Cons:缺点:

Doesn't enforce usage of constructor injection不强制使用构造函数注入

I've faced the same problem I've fixed it by using Mockito.mock() method instead of @Mock.我遇到了同样的问题,我通过使用 Mockito.mock() 方法而不是 @Mock 来解决它。

In my case the error occurred because in initMocks method from MockitoTestExecutinListener class looks like this:在我的情况下,发生错误是因为在 MockitoTestExecutinListener class 的 initMocks 方法中看起来像这样:

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

but in my case MockitoAnnotations have only initMocks() method, so the error.但在我的情况下,MockitoAnnotations 只有 initMocks() 方法,所以错误。

In this case we need to make sure that hasMockitoAnnotations(testContext) is false.在这种情况下,我们需要确保 hasMockitoAnnotations(testContext) 为 false。 In order to use @Mock I need to enable Mockito annotations, but I do not want this, therefore I used Mockito.mock().为了使用@Mock,我需要启用 Mockito 注释,但我不想要这个,因此我使用了 Mockito.mock()。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM