首页 > 解决方案 > 具有等待性和 @SpyBean 的 Spring Boot 集成测试不起作用,因为 @SpyBean 始终为空

问题描述

我想测试我的计划任务,所以我按照这个教程

@SpringJUnitConfig(SchedulerConfig.class)
public class MailJobFinderTaskIT {

    @SpyBean
    private MailJobFinderTask mailJobFinderTask;

    @Test
    public void whenWaitThreeSecond_ThenTaskCalledThreeTimes(){
        await()
            .atMost(Duration.ofSeconds(3))
            .untilAsserted(() -> verify(mailJobFinderTask, atLeast(3)).findEmailJobs());
    }

}

但实际上它不起作用,因为以下错误

 org.mockito.exceptions.misusing.NullInsteadOfMockException:
        Argument passed to verify() should be a mock but is null!
        Examples of correct verifications:
        verify(mock).someMethod();
        verify(mock, times(10)).someMethod();
        verify(mock, atLeastOnce()).someMethod();
        not: verify(mock.someMethod());
        Also, if you use @Mock annotation don't miss initMocks()

这是我的任务班的签名

@Component
public class MailJobFinderTask extends SuppressedLogPoller {
....
}

 @Scheduled(fixedRate = 1000)
 public void findEmailJobs() {
 .
 .
 }

我已经尝试将注释更改为 @SpringBootTest 并且还尝试使用 @MockBean 而不是 @SpyBean 但没有任何成功。其实我不明白为什么我的 bean mailJobFinderTask 没有创建

标签: javaspring-bootawaitility

解决方案


您的代码似乎在我的系统上运行良好,但我不得不做一些更改。

我会推荐这些作为您故障排除的起点。此外,您还没有提到是否可以成功复制链接的教程,该教程在我的系统上也可以正常运行。如果您还没有,我建议您先尝试本教程,确认它有效,然后添加您自己的代码。

如果以下内容对您没有帮助,那么问题可能不在您发布的代码部分。在这种情况下,共享完整代码将有助于我们更好地解决问题。但就目前而言,也许要特别注意导入语句和下面列出的主要更改。

代码更改

  1. 我将Duration.ofSeconds(3)方法更改为Duration.FIVE_SECONDS。原因是前者来自 java.time 包,而 await() 期望来自 awaitility 包的 Duration 类。我只是出于兼容性目的使用了 FIVE_SECONDS。
  2. 我不得不删除“扩展 SuppressedLogPoller”部分,因为我无权访问此类。我还建议删除它并再次添加它以查看它是否导致问题。

测试类代码

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;


import org.awaitility.Duration;

import static org.awaitility.Awaitility.await;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.verify;


@SpringJUnitConfig(ScheduledConfig.class)
public class MailJobFinderTaskIT {

    @SpyBean
    private MailJobFinderTask mailJobFinderTask;

    @Test
    public void whenWaitThreeSecond_ThenTaskCalledThreeTimes(){
        await()
                .atMost(Duration.FIVE_SECONDS)
                .untilAsserted(() -> verify(mailJobFinderTask, atLeast(7)).findEmailJobs());
    }
}

领域类

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class MailJobFinderTask {

    @Scheduled(fixedRate = 1200)
    public void findEmailJobs() {

    }

}

推荐阅读