How to fix this error: 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>
遇到同样的问题后。请查看日志跟踪。
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() 方法,该方法已弃用并替换为 MockitoAnnotations.openMocks() 在 Mockito JUnit 5 版本 3 中。 MockitoAnnotations.openMocks() 方法 returns 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 注入或字段注入。
优点:
易于注入模拟
缺点:
不强制使用构造函数注入
对我来说,none 此处提到的解决方法无效。
Updating mockito-core
from 3.3.3
to 3.4.3
fixed the problem.
我认为这是由于 MockitoAnnotations.initMock() 方法在 Mockito JUnit 5 版本 3 中被弃用并替换为 MockitoAnnotations.openMocks() 造成的。
另一方面,可能值得检查本地Maven Repository并删除可能导致冲突的不必要的jar。但是在应用这个步骤的时候要注意不要删除手动安装的(或者操作前做好备份)。
我遇到了同样的问题我已经通过使用修复了它
Mockito.mock() 方法而不是 @Mock。
我使用 spring-boot-starter-test v2.4.8 和 mockito-core v2.21.0
在我的例子中,错误发生是因为在 MockitoTestExecutinListener 的 initMocks 方法中 class 看起来像这样:
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().
所以我在我的 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>
遇到同样的问题后。请查看日志跟踪。
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() 方法,该方法已弃用并替换为 MockitoAnnotations.openMocks() 在 Mockito JUnit 5 版本 3 中。 MockitoAnnotations.openMocks() 方法 returns 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 注入或字段注入。
优点:
易于注入模拟
缺点:
不强制使用构造函数注入
对我来说,none 此处提到的解决方法无效。
Updating
mockito-core
from3.3.3
to3.4.3
fixed the problem.
我认为这是由于 MockitoAnnotations.initMock() 方法在 Mockito JUnit 5 版本 3 中被弃用并替换为 MockitoAnnotations.openMocks() 造成的。
另一方面,可能值得检查本地Maven Repository并删除可能导致冲突的不必要的jar。但是在应用这个步骤的时候要注意不要删除手动安装的(或者操作前做好备份)。
我遇到了同样的问题我已经通过使用修复了它 Mockito.mock() 方法而不是 @Mock。
我使用 spring-boot-starter-test v2.4.8 和 mockito-core v2.21.0
在我的例子中,错误发生是因为在 MockitoTestExecutinListener 的 initMocks 方法中 class 看起来像这样:
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().