【发布时间】:2017-12-22 19:23:37
【问题描述】:
我正在编写一个 sidecar 微服务,它将 TCP 与旧版应用程序通信,并在另一端使用 rabbitMQ。我刚刚开始编写测试,以便更好地了解一切是如何工作的,因为我是 Spring 新手。我的应用程序构建、部署和运行良好。
但是,编写干净的测试有点复杂。我一直在将我的代码从 spring-integration tcp 基本示例中提取出来。我开始使用一个模拟 TCPServer 来测试我在测试类之外定义的代码。但是模拟 TCPServer 一直在为每个测试类构建。所以我把它移到了类似于我found的例子的TCPGatewayTest类中。
这导致了一些缺少的 bean 问题,这导致我添加了一个 @ContextConfiguration 注释,这让我更进一步。但现在我还有其他缺失的豆子。我确定我用@ContextConfiguration 搞乱了我的ApplicationContext。有没有更好的方法来使用不同的注释或略有不同?我不会走 xml 路线,如果可能的话,我想避开它。
熟悉的无限定bean错误:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.amqp.rabbit.connection.ConnectionFactory' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
我的测试类如下
package org.inc.imo;
@ComponentScan("org.inc")
@ContextConfiguration(classes = {TCPGatewayTest.TCPServerMock.class,
org.inc.imo.Configuration.TCPConfig.class,
org.inc.imo.Configuration.RabbitConfig.class })
@TestPropertySource(locations= "classpath:test.properties")
@RunWith(SpringRunner.class)
@SpringBootTest
public class TCPGatewayTest {
@Autowired
private TCPGateway gateway;
@Autowired
AbstractServerConnectionFactory crLfServer;
@Before
public void setup() {
TestingUtilities.waitListening(this.crLfServer, 10000L);
}
@Test
public void testConnectionToMockServer() {
String result = gateway.send("Hello World");
assertEquals("HELLO WORLD", result);
}
@Configuration
@MessageEndpoint
public static class TCPServerMock {
@Value("${imo.port}")
private int port;
@Bean()
public AbstractServerConnectionFactory serverCF() {
return new TcpNetServerConnectionFactory(this.port);
}
@Transformer(inputChannel="fromTcp", outputChannel="toEcho")
public String convert(byte[] bytes) {
return new String(bytes);
}
@ServiceActivator(inputChannel="toEcho")
public String upCase(String in) {
return in.toUpperCase();
}
@Bean
public TcpInboundGateway tcpInGate(AbstractServerConnectionFactory connectionFactory) {
TcpInboundGateway inGate = new TcpInboundGateway();
inGate.setConnectionFactory(connectionFactory);
inGate.setRequestChannel(fromTcp());
return inGate;
}
@Bean
public MessageChannel fromTcp() {
return new DirectChannel();
}
}
}
兔子配置类
package org.inc.imo.configuration;
@EnableIntegration
@IntegrationComponentScan
@ComponentScan
@Configuration
public class RabbitConfig {
public final static String IMO_REQUEST_JEA = "imo.request.jea";
public final static String IMO_REQUEST_INFO = "imo.request.info";
@Bean
public AmqpAdmin amqpAdmin(final ConnectionFactory connectionFactory) {
RabbitAdmin admin = new RabbitAdmin(connectionFactory);
admin.declareQueue(jeaRequestQueue());
admin.declareQueue(infoRequestQueue());
return admin;
}
@Bean
public Queue jeaRequestQueue() {
return new Queue(IMO_REQUEST_JEA);
}
@Bean
public Queue infoRequestQueue() {
return new Queue(IMO_REQUEST_INFO);
}
@Bean
public RabbitTemplate rabbitTemplate(final ConnectionFactory connectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
return rabbitTemplate;
}
@Bean
public ObjectWriter objectWriter() {
return new ObjectMapper().writer();
}
}
TCPConfig 类
package org.inc.imo.configuration;
@EnableIntegration
@IntegrationComponentScan
@ComponentScan
@Configuration
public class TCPConfig {
@Value("${imo.hostname}")
private String host;
@Value("${imo.port}")
private int port;
private static MessageChannel sendChannel;
private static MessageChannel replyChannel;
@Bean
public MessageChannel replyChannel() {
replyChannel = new DirectChannel();
return replyChannel;
}
@Bean(name="sendChannel")
public MessageChannel sendChannel() {
MessageChannel directChannel = new DirectChannel();
sendChannel = directChannel;
return directChannel;
}
@Bean
public TcpNetClientConnectionFactory connectionFactory() {
TcpNetClientConnectionFactory connectionFactory = new TcpNetClientConnectionFactory(host, port);
connectionFactory.setSingleUse(false);
return connectionFactory;
}
@Bean
@ServiceActivator(inputChannel = "sendChannel")
public TcpOutboundGateway tcpOutboundGateway() {
TcpOutboundGateway tcpOutboundGateway = new TcpOutboundGateway();
tcpOutboundGateway.setConnectionFactory(connectionFactory());
tcpOutboundGateway.setReplyChannel(this.replyChannel());
tcpOutboundGateway.setRequiresReply(true);
return tcpOutboundGateway;
}
}
TCPGateway 接口
package org.inc.imo.Domain;
@MessagingGateway(defaultRequestChannel = "sendChannel")
public interface TCPGateway {
String send(String message);
}
【问题讨论】:
标签: spring rabbitmq spring-integration