传递给 when() 的参数不是模拟的! Spring 没有@SpringBootApplication/main class 的引导项目抛出异常
Argument passed to when() is not a mock! exception thrown with Spring Boot project which doesn't have @SpringBootApplication/main class
我的项目是一个简单的 spring 启动应用程序,它没有 main/@SpringBootApplication class。它用作其他模块的依赖库。我正在尝试为这个项目中存在的 classes 编写单元测试,如下所示,并得到下面粘贴的错误。非常感谢任何快速帮助。
pom 依赖项:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<!-- exclude junit 4 -->
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- junit 5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
由于此项目没有主 class,使用以下配置获取 spring 应用程序上下文 class。
@Configuration
public class TestServiceConfig {
@Bean
public TestService productService() {
return Mockito.mock(TestService.class);
}
@Bean
public MongoDriverService productMongo() {
return Mockito.mock(MongoDriverService.class);
}
}
下面是我的测试 class,它抛出异常。实际 java class 有一个名为 getPlanCode 的方法(需要 6 个参数)和 returns void。在此方法中,mongo 对象用于连接数据库,因此我在服务对象上使用了@InjectMocks。
public class ValidationServiceTest {
@Mock
MongoDriverService mongo;
@InjectMocks
TestService service;
@Test
@DisplayName("Test Get Plan Code positive")
public void getPlanCodeTest() {
doNothing().when(service).getPlanCode(anyString(), anyString(), any(Batch.class), any(BatchFile.class), any(Document.class), anyString());
service.getPlanCode(anyString(), anyString(), any(Batch.class), any(BatchFile.class), any(Document.class), anyString());
verify(service, times(1)).getPlanCode(anyString(), anyString(), any(Batch.class), any(BatchFile.class), any(Document.class), anyString());
}
}
以下是例外
12:51:33.829 [main] DEBUG org.springframework.test.context.support.AbstractDirtiesContextTestExecutionListener - After test method: context [DefaultTestContext@45b4c3a9 testClass = DefaultMedicareBFTAccumsValidationServiceTest, testInstance = com.anthem.rxsmart.service.standalone.batchvalidation.DefaultMedicareBFTAccumsValidationServiceTest@14dda234, testMethod = getPlanCodeTest@DValidationServiceTest, testException = org.mockito.exceptions.misusing.NotAMockException:
Argument passed to when() is not a mock!
Example of correct stubbing:
service
不是模拟,因为您使用的是 @InjectMocks
(假设您使用的是 @RunWith(MockitoRunner.class)
或 @ExtendWith
,但您出于某种原因隐藏了它)。
@InjectMocks
所做的,是创建一个新的 TestService
实例,并将模拟注入其中(模拟所需的依赖项)。所以服务是真的,不是假的
IMO 此测试没有意义,因为您应该测试单一实体合同的实施,而不是测试模拟...
你的测试用例和断言毫无意义,因为它就像“调用方法 A 并检查我是否刚刚调用了方法 A”,而你应该检查和验证例如 return 调用的值,或者某些方法是否的模拟已被调用,例如,如果 Mongo 是用适当的参数查询的。我只是希望这是一个非常糟糕的例子,而不是真实的测试场景
测试设置也是错误的,因为你告诉我们你想使用 @Configuration
class 和 @Bean
但是你在测试中使用 @Mock
为您创建全新的模拟。换句话说 - 根本没有使用该配置
贴出此答案,仅供相同理解状态的开发者使用。
@Test
@DisplayName("Test Get Plan Code positive")
public void getPlanCodeTest() {
service = new ValidationService(mongo);
Mockito.when(mongo.aggregateIterable("test", pipeline)).thenReturn(tierFilterDocs);
service.getPlanCode("", "", null, batchFile, null, "");
verify(mongo, times(1)).aggregateIterable("test", pipeline);
}
我已经更新了我的测试用例,现在它解决了这个问题。现在不需要配置文件,因为我正在测试 class 本身中模拟对象。
我的项目是一个简单的 spring 启动应用程序,它没有 main/@SpringBootApplication class。它用作其他模块的依赖库。我正在尝试为这个项目中存在的 classes 编写单元测试,如下所示,并得到下面粘贴的错误。非常感谢任何快速帮助。
pom 依赖项:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<!-- exclude junit 4 -->
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- junit 5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
由于此项目没有主 class,使用以下配置获取 spring 应用程序上下文 class。
@Configuration
public class TestServiceConfig {
@Bean
public TestService productService() {
return Mockito.mock(TestService.class);
}
@Bean
public MongoDriverService productMongo() {
return Mockito.mock(MongoDriverService.class);
}
}
下面是我的测试 class,它抛出异常。实际 java class 有一个名为 getPlanCode 的方法(需要 6 个参数)和 returns void。在此方法中,mongo 对象用于连接数据库,因此我在服务对象上使用了@InjectMocks。
public class ValidationServiceTest {
@Mock
MongoDriverService mongo;
@InjectMocks
TestService service;
@Test
@DisplayName("Test Get Plan Code positive")
public void getPlanCodeTest() {
doNothing().when(service).getPlanCode(anyString(), anyString(), any(Batch.class), any(BatchFile.class), any(Document.class), anyString());
service.getPlanCode(anyString(), anyString(), any(Batch.class), any(BatchFile.class), any(Document.class), anyString());
verify(service, times(1)).getPlanCode(anyString(), anyString(), any(Batch.class), any(BatchFile.class), any(Document.class), anyString());
}
}
以下是例外
12:51:33.829 [main] DEBUG org.springframework.test.context.support.AbstractDirtiesContextTestExecutionListener - After test method: context [DefaultTestContext@45b4c3a9 testClass = DefaultMedicareBFTAccumsValidationServiceTest, testInstance = com.anthem.rxsmart.service.standalone.batchvalidation.DefaultMedicareBFTAccumsValidationServiceTest@14dda234, testMethod = getPlanCodeTest@DValidationServiceTest, testException = org.mockito.exceptions.misusing.NotAMockException:
Argument passed to when() is not a mock!
Example of correct stubbing:
service
不是模拟,因为您使用的是 @InjectMocks
(假设您使用的是 @RunWith(MockitoRunner.class)
或 @ExtendWith
,但您出于某种原因隐藏了它)。
@InjectMocks
所做的,是创建一个新的 TestService
实例,并将模拟注入其中(模拟所需的依赖项)。所以服务是真的,不是假的
IMO 此测试没有意义,因为您应该测试单一实体合同的实施,而不是测试模拟...
你的测试用例和断言毫无意义,因为它就像“调用方法 A 并检查我是否刚刚调用了方法 A”,而你应该检查和验证例如 return 调用的值,或者某些方法是否的模拟已被调用,例如,如果 Mongo 是用适当的参数查询的。我只是希望这是一个非常糟糕的例子,而不是真实的测试场景
测试设置也是错误的,因为你告诉我们你想使用 @Configuration
class 和 @Bean
但是你在测试中使用 @Mock
为您创建全新的模拟。换句话说 - 根本没有使用该配置
贴出此答案,仅供相同理解状态的开发者使用。
@Test
@DisplayName("Test Get Plan Code positive")
public void getPlanCodeTest() {
service = new ValidationService(mongo);
Mockito.when(mongo.aggregateIterable("test", pipeline)).thenReturn(tierFilterDocs);
service.getPlanCode("", "", null, batchFile, null, "");
verify(mongo, times(1)).aggregateIterable("test", pipeline);
}
我已经更新了我的测试用例,现在它解决了这个问题。现在不需要配置文件,因为我正在测试 class 本身中模拟对象。