【问题标题】:Argument passed to when() is not a mock! exception thrown with Spring Boot project which doesn't have @SpringBootApplication/main class传递给 when() 的参数不是模拟!没有 @SpringBootApplication/main 类的 Spring Boot 项目引发的异常
【发布时间】:2022-02-03 07:37:16
【问题描述】:

我的项目是一个简单的 Spring Boot 应用程序,它没有 main/@SpringBootApplication 类。它用作其他模块的依赖库。我正在尝试为该项目中存在的类编写单元测试,如下所示,并得到以下粘贴错误。非常感谢任何快速帮助。

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>

由于本项目没有主类,所以使用下面的配置类来获取spring应用上下文。

@Configuration
public class TestServiceConfig {
@Bean
public TestService productService() {
    return Mockito.mock(TestService.class);
}

@Bean
public MongoDriverService productMongo() {
    return Mockito.mock(MongoDriverService.class);
}
}

下面是我抛出异常的测试类。实际的 java 类有一个名为 getPlanCode 的方法(它需要 6 个参数)并返回 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:

【问题讨论】:

    标签: spring-boot mockito junit5 spring-boot-test


    【解决方案1】:

    service 不是模拟,因为您使用的是 @InjectMocks(假设您使用的是 @RunWith(MockitoRunner.class)@ExtendWith,但无论出于何种原因您都在隐藏它)。

    @InjectMocks 所做的是创建TestService 的新实例,并将模拟注入其中(模拟所需的依赖项)。所以服务是真实的,不是模拟的

    IMO 这个测试没有意义,因为你应该测试你的单一实体合约的实现,而不是测试模拟......

    您的测试用例和断言毫无意义,因为它就像“调用方法 A 并检查我是否刚刚调用了方法 A”,而您应该检查和验证例如调用的返回值,或者是否调用了某些模拟方法,例如如果使用适当的参数查询 Mongo。我只是希望这是一个非常糟糕的例子,而不是真正的测试场景

    测试设置也是错误的,因为您向我们展示了您希望将 @Configuration 类与 @Bean 一起使用,但随后您在测试中使用了 @Mock,这将为您创建全新的模拟。换句话说-根本没有使用该配置

    【讨论】:

    • 其实我是从一些文章中收集到这些知识的,所以它有差距。您能否帮助我遵循正确的流程来编写测试用例来测试我的服务方法和其中的 mongo 调用。
    • 测试功能是一个与实现这些功能一样广泛的话题,所以我不能在这里解释你的问题。无论它是否是 mongo,它都是一个可以模拟以测试您的服务以及它是否与依赖项正确交互的依赖项。尝试用谷歌搜索“junit injection mocks example”并阅读一些关于如何编写单元测试的文献(youtube 也包含一些有价值的讲座)
    【解决方案2】:

    仅针对处于相同理解状态的开发人员发布此答案。

    @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);        
    }
    

    我已经更新了我的测试用例,所以它现在解决了这个目的。现在不需要配置文件,因为我正在模拟测试类本身的对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-22
      • 1970-01-01
      • 2017-06-03
      • 2021-04-06
      • 1970-01-01
      • 1970-01-01
      • 2016-11-19
      • 2015-05-23
      相关资源
      最近更新 更多