Junit / Spring Boot 模拟类

Posted

技术标签:

【中文标题】Junit / Spring Boot 模拟类【英文标题】:Junit / Spring Boot mocking classes 【发布时间】:2018-03-09 04:31:23 【问题描述】:

我使用 Spring Initializr 生成了一个 Spring Boot Web 应用程序,使用嵌入式 Tomcat + Thymeleaf 模板引擎,并打包为可执行 JAR 文件。

使用的技术:

Spring Boot 1.4.2.RELEASE、Spring 4.3.4.RELEASE、Thymeleaf 2.1.5.RELEASE、Tomcat 嵌入 8.5.6、Maven 3、Java 8

我有这门课 我有这个junit测试类:

@ContextConfiguration(classes=TestPersistenceConfig.class)
@RunWith(SpringRunner.class)
@SpringBootTest
public class JdbcRemoteUnitRepositoryTests 

    @Autowired
    private JdbcRemoteUnitRepository repository;

    @Autowired
    @InjectMocks
    private SmsConfig smsConfig;

    @Autowired
    @InjectMocks
    private NextelSMSSender  smsService;

    @Before
    public void setup() 
        MockitoAnnotations.initMocks(this);
    

    @Test   
    public void testGetAllUnits() throws DataAccessException, SQLException         
        Assert.assertTrue(true);
    


NextelSMSSender 类:

@Service("smsService")
public class NextelSMSSender  

    public final static String OK_STATUS_CODE = "200";

    @Autowired
    SmsConfig smsConfig;
..

.

@Configuration
@PropertySource("sms-gateway.properties")
public class SmsConfig 

    @Value("$sms.domainId")
    private String domainId;

    @Value("$sms.gateway.url")
    private String gatewayUrl;
..

但似乎不是在模拟 objects 属性,因为当我打包应用程序时。我收到了这个错误:

***************************
APPLICATION FAILED TO START
***************************

Description:

Field smsConfig in com.plats.bruts.NextelSMSSender required a bean of type 'com.plats.bruts.config.SmsConfig' that could not be found.

Action:

Consider defining a bean of type 'com.plats.bruts.config.SmsConfig' in your configuration.

我创建了一个名为TestSmsConfig的mock bean,尝试添加@Bean,但出现编译错误:

The annotation @Bean is disallowed for this 
 location

    @Configuration
    @Bean
    public class TestSmsConfig 

        @Value("fake.domainId")
        private String domainId;

        @Value("fake.sms.gateway.url")
        private String gatewayUrl;

         ...

【问题讨论】:

【参考方案1】:

您正在自动装配 smsConfig,但您似乎没有在测试应用程序上下文中提供该 @Bean。

此外,您错误地使用了@InjectMocks - 这应该用于将模拟对象注入到被测类(您的 NextelSMSSender 类,而不是 SmsConfig)中。

要解决此问题,请在配置类中添加 @Bean 方法以提供 SmsConfig bean 实例。

用@MockBean 替换测试类中SmsConfig 变量中的@InjectMocks。 SmsConfig 是一个自动装配的模拟对象,而不是被测试的类。

请参阅第 41.3.4 节 - Spring Boot Testing Features 以了解更多信息:

Spring Boot 包含一个 @MockBean 注解,可用于定义 一个 Mockito 模拟你的 ApplicationContext 中的一个 bean。您可以使用 添加新 bean 或替换单个现有 bean 的注释 定义。注释可以直接在测试类上使用,在 测试中的字段,或 @Configuration 类和字段。什么时候 在字段上使用时,创建的模拟实例也将是 注入。模拟 bean 在每个测试方法之后都会自动重置。

【讨论】:

【参考方案2】:

好的,这就是你的配置:

    @Configuration
    @PropertySource("sms-gateway.properties")
    public class SmsConfig 

    @Value("$sms.domainId")
    private String domainId;

    @Value("$sms.gateway.url")
    private String gatewayUrl;
..

如果您想在测试中使用该配置,您应该将其添加到您的配置类中...

@ContextConfiguration(classes=TestPersistenceConfig.class, SmsConfig.class)

不要将其添加为 @Autowired 或其他。

【讨论】:

以上是关于Junit / Spring Boot 模拟类的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 JUnit 在 Spring Boot 中的公共方法中模拟私有方法

在 JUnit 5 测试中模拟 Spring Boot 2 应用程序的自动装配依赖项

如何在 Spring Boot REST API 中为 db insert 方法编写模拟单元测试?

@MockBean 不适用于带有 JUnit 5 和 Spring Boot 2 的 @WebMvcTest?

JUnit、Mockito 和 Spring ApplicationContext:模拟属性时遇到问题

Spring JUnit:如何在自动装配组件中模拟自动装配组件