【问题标题】:Mocking of RestTemplate is with spring boot 2.x is throwing null pointer exceptionRestTemplate 的模拟是用 spring boot 2.x 抛出空指针异常
【发布时间】:2021-10-01 21:28:20
【问题描述】:

我正在为调用 REST 后端服务和 MongoDB 的服务层编写单元测试。但是,当在本地执行我的测试时工作正常,但是在编译期间将我的应用程序打包到我的 CICD 管道中时,它会尝试运行单元测试,同时在使用 RestTemplateMongoTemplate bean 时会出现空指针异常。

MyTestService {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private MongoTemlate mongoTemplate;

    public String callDBAndBackend() {

        // some business logic
        UpdatedObject mongoDoc = mongoTemplate.updateFirst(updateObject);

        restTemplate.exchange(reqEntity, ResponseObject.class);
        return "Success";
    }
}
@ExtendWith(MockitoExtension.class)
MyTestServiceTest {

    @Mock
    private RestTemplate restTemplate;

    @Mock
    private MongoTemplate mongoTemplate;


    @InjectMocks
    private MyTestService myTestService;

    @Test
    public void testCallDBAndBackend() {

        when(restTemplate.exchange(reqEntity, ResponseObject.class)).thenReturn("Success"); // In this line getting Null pointer. Cant able to inject restTemplate
        when(mongoTemplate.updateFirst(updateObject)).thenReturn("Success"); // In //this line getting Null pointer. Cant able to inject mongoTemplate

    myTestService.callDBAndBackend();

    }
}

pom.xml

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
    </parent>

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
    <!--    <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>  -->
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
        </dependency>

编译此代码时,我将 RestTemplate 和 MongoTemplate 对象设为 null,这会导致 NPL。如果我从 IDE 运行相同的代码,它可以正常工作并获得有效的 RestTemplate 和 MongoTemplate 模拟对象。

【问题讨论】:

  • 你能添加你的测试类的导入吗?是否可以在同一个测试中混合使用 JUnit 4 和 JUnit 5?

标签: unit-testing mockito spring-boot-test


【解决方案1】:

您可以对目标类MyTestService 使用InjectMocks 注释来注入模拟对象。

您的解决方案应该为您提供 NLP,因为您没有将模拟对象提供给 MyTestService

@ExtendWith(MockitoExtension.class)
MyTestServiceTest{

@InjectMocks
private MyTestService service;

@Mock
private RestTemplate restTemplate;

@Mock
private MongoTemplate mongoTemplate;

@Test
public void testCallDBAndBackend() {
    // Arrange
    when(restTemplate.exchange(reqEntity,ResponseObject.class))
    .thenReturn("Success");
    when(mongoTemplate.updateFirst(updateObject)).thenReturn("Success");

     // Act
     String actual = service.callDBAndBackend();

     // Assert
     ...
    }
}

【讨论】:

  • 我刚刚用 '@'InjectMock 注释更新了我的问题,但我仍然遇到同样的问题。这里的问题是我无法在我的 UnitTesting 上下文中获取 Spring 特定的 bean,而 build.Same 工作正常,如果从我的 IDE 单独执行我的代码。我怀疑在构建期间测试上下文无法使用依赖于 spring 的 bean。同样的代码在 Junit4 中运行良好
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-17
相关资源
最近更新 更多