spring-boot 2在Junit中注入Bean RabbitTemplate的问题

时间:2019-06-11 16:04:23

标签: spring-boot rabbitmq junit4

我有一些小问题,在Spring-boot中运行时注入Bean可以正常工作,但使用Junit可以正常工作。我有RabbitTemplate

的示例
 public class NettyServerRun {

    @Autowired
    private IDeviceClient deviceClientComponent;
    @Autowired
    private ServiceDeviceServer service;

    @Autowired
    private RabbitManager mqService;

    private int port = 7650;

    @PostConstruct
    public void init() throws InterruptedException {
        NioEventLoopGroup boosGroup = new NioEventLoopGroup();
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(boosGroup, workerGroup);
        bootstrap.channel(NioServerSocketChannel.class);
        final EventExecutorGroup group = new DefaultEventExecutorGroup(1500); 
        bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
        @Override
        protected void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast(workerGroup,new 
        RequestDecoderServer(deviceClientComponent)); 
        pipeline.addLast(workerGroup,new ResponseEncoderServer()); 
        pipeline.addLast(group,new AuthenticateHandler(service));
        pipeline.addLast(group,new CommandResponseHandler(service));
        pipeline.addLast(group,new DeviceDataHandler(mqService));
    }
        });
        ChannelFuture f = bootstrap.bind(port).sync();
        f.channel().closeFuture().sync();
    }
    @RunWith(SpringRunner.class)
    @DataJpaTest
    @Import(NettyServerRun.class)
    @AutoConfigureTestDatabase(replace=Replace.ANY)
    @ComponentScan("com.metier")
    public abstract class DeviceServerTest {

    @Autowired
    protected TestEntityManager entityManager;

    @Autowired
    protected ServiceDeviceServer service;

    @Autowired
    protected TestRestTemplate template;


    protected DeviceServerContext context;
    protected Gson gson;
    protected Nmea nmeaData;

    @Value("${spring.profiles.active}")
    private String activeProfile;


    protected void persistList(List<AbstractEntity> list) {
        list.forEach(entity -> entityManager.persist(entity));
    }

    public GpsCmdRsp buidGpsCmdRsp(Long gpsId) {
        GpsCmdRsp reference = new GpsCmdRsp();
        reference.setCommand("*TS01,188765,NAM#");
        reference.setCompletedAt(buildHier());
        reference.setGpsId(gpsId);
        reference.setResponse("*TS01,353836057694499,013809281017,NAM:ODO50- 
        BLE#");
        reference.setSuccess(false);
        return reference;
     }
  public class DeviceDataHandlerTest extends DeviceServerTest {

    @Autowired
    private NettyServerRun nettyServerRun;

    @Before
    public void setUp() {

    }

    @Test
    public void channelReadDeviceExistTest() {
        String[] trame = {
             "*TS01,351579056605817,003410140618,GPS:3;N46.758156;W71.134046;6;0;0.96,STT:c003;8001,MGR:957975,SAT:43;40;39#" };
        EmbeddedChannel channel = new EmbeddedChannel(new DeviceDataHandler());
        boolean ok = channel.writeInbound(trame);
        assertThat(ok).isTrue();

    }

}

错误日志

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.amqp.rabbit.core.RabbitTemplate' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1654) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1213) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1167) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593) ~[spring-beans-5.1.6.RELEASE.jar:5.1.6.RELEASE]
... 44 common frames omitted ##

所以,就像我说的那样。如果我仅与Spring-Boot一起运行,则RabbitTemplate注入工作正常。但是,如果和Junit一起跑步。我尝试添加@SpringBootTest

java.lang.IllegalStateException: Configuration error: several statements found from @BootstrapWith for test class [com.AuthenticateHandlerTest]: [@ org.springframework.test.context.BootstrapWith (value = class org.springframework.boot.tocon. test.autoconfigure.orm .jpa.DataJpaTestContextBootstrapper), @ org.springframework.test.context.BootstrapWith (value = class org.springframework.boot.test.context.SpringBootTestContextBootstrapper)]
at org.springframework.test.context.BootstrapUtils.resolveExplicitTestContextBootstrapper (BootstrapUtils.java:166)
org.springframework.test.context.BootstrapUtils.resolveTestContextBootstrapper (BootstrapUtils.java:127). 

由于@DataJpaTest

2 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,我不得不模拟使用RabbitTemplate的bean。

将此注释放在测试的类名的顶部:

@MockBean(RabbitManager.class)

对于其他任何人,该类将是包含RabbitTemplate字段的类,即:

@MockBean(MyServiceContainingRabbitTemplate.class)

但这使我提出疑问,为什么我必须这样做。我想知道:)

答案 1 :(得分:0)

测试中的@DataJpaTest批注用于扫描@Entity,存储库,EntityManager和其他在测试中使用数据库所需的bean,但是此批注不会加载常规的{{ 1}}豆放入@Component中。

在测试用例中,可以使用ApplicationContext注释代替@SpringBootTest来加载整个应用程序上下文。