在 Spring Boot 单元测试中,可以通过使用 @MockBean或者自定义配置来实现按需加载Bean,避免加载不必要的组件。
比如在测试 TopicProducer 类时,
而在 TopicConsumer 类中的一些配置会影响到测试的进行,需要排除。
方法一:使用@MockBean忽略不需要的Bean
java
package com.taj.rabbit.exchange.topic;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
@SpringBootTest
class TopicProducerTest {
@Resource
TopicProducer topicProducer;
// 使用 @MockitoBean 来替代真实的 Bean,以达到禁用加载的目的
@MockitoBean(name = "topicConsumer")
TopicConsumer topicConsumer;
@Test
void init() {
topicProducer.init();
}
@Test
void send() {
topicProducer.send();
}
}
方法二:使用classes属性指定加载类
上面的注解 @SpringBootTest 无参,默认会寻找应用启动类
即等价于 @SpringBootTest(classes = RabbitApplication.class)
其中 RabbitApplication.class 就是应用启动类:
java
@SpringBootApplication
public class RabbitApplication {
public static void main(String[] args) {
SpringApplication.run(RabbitApplication.class, args);
}
}
这种方式会加载完整的Spring Boot应用程序上下文:
- 真实环境模拟:更接近实际运行环境,会初始化所有配置、数据库连接、外部服务等
- 启动时间较长:因为要加载整个应用上下文,所以测试启动较慢
如果只想加载一个多或多个类,可以直接写在 classes 参数中,如下:
java
package com.taj.rabbit.exchange.topic;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest(classes = TopicProducer.class)
@EnableAutoConfiguration // 开启自动配置功能,测试连接 rabbitmq
class TopicProducerTest {
@Resource
TopicProducer topicProducer;
@Test
void init() {
topicProducer.init();
}
@Test
void send() {
topicProducer.send();
}
}
如果测试需要连接真实的 rabbitmq,数据库等,则开启自动配置功能。
如果 application.yaml 配置文件很大,会启用很多自动配置,而我只需要启用 rabbit
可以修改如下:
java
package com.taj.rabbit.object2json;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import java.util.Map;
//@SpringBootTest(classes = {ObjectPublisher.class, RabbitConfig.class})
//更轻量的一种方式:
@SpringJUnitConfig(classes = {ObjectPublisher.class, RabbitConfig.class})
//@TestPropertySource(locations = "classpath:rabbit.properties")
@TestPropertySource(
properties = {
"spring.application.name=rabbit",
"spring.rabbitmq.addresses=192.168.2.11:5672",
"spring.rabbitmq.username=admin",
"spring.rabbitmq.password=admin123",
"spring.rabbitmq.virtual-host=/",
"spring.rabbitmq.listener.simple.prefetch=1"
}
)
@EnableAutoConfiguration
class ObjectPublisherTest {
@Resource
private ObjectPublisher objectPublisher;
@Test
void send() {
// 测试:发送 Object 消息
Map<String, Object> message = Map.of("name", "Taj", "age", 18);
System.out.println("[发送1个消息给队列 " + RabbitConfig.QUEUE_NAME + "]");
objectPublisher.send(message);
}
}