我有一个运行Spring云合约的Spring启动应用程序
MessageTest. groovy
Contract.make {
label 'some_label'
input {
triggeredBy('messageTriggered()')
}
outputMessage {
sentTo 'verifications'
body 'foo'
headers {
messagingContentType(applicationJson())
}
}
}
我的测试失败了,当我在构建文件夹中查看生成的测试时,
ContractVerifierMessage response = contractVerifierMessaging.receive("verifications");
上面这一行一直抛出异常
No bean named 'verifications' available
我做错了什么?
它看起来像是注入SpringIntegrationStubMessages
而不是StreamStubMessages
…
我使用Spring Boot 1.5.8与Spring Cloud Starterkafka
compile 'org.springframework.cloud:spring-cloud-starter-stream-kafka'
如果您在类路径上同时具有Spring集成和流,并且由于某种原因流未被拾取,则尝试将stubrunner.集成.启用
设置为false
。这样应该只选择Stream。
我猜您需要MessageVerifier bean作为StreamStubMessages类的实例。它是一个条件的,它的实例化取决于类路径的内容。您可以尝试通过显式实例化来解决问题:
@Bean
MessageVerifier<Message<?>> activeMqContractVerifier(ApplicationContext applicationContext) {
return new StreamStubMessages(applicationContext);
}
它应该以没有类def发现异常结束,这将引导您找到缺少的依赖项。
我也遇到过类似的问题,但在我的例子中,有ActiveMQ代替了Kafka(没有Spring集成或Spring流)。因此,可用的MessageVerifier似乎都不合适。对我来说,MessageVerifier的以下简约实现(它不是ActiveMQ的通用解决方案)完成了这项工作:
import org.springframework.cloud.contract.verifier.messaging.MessageVerifier;
import org.springframework.context.ApplicationContext;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.support.converter.MessagingMessageConverter;
import org.springframework.messaging.Message;
import javax.jms.JMSException;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public class ActiveMqStubMessages implements MessageVerifier<Message<?>> {
private final ApplicationContext applicationContext;
public ActiveMqStubMessages(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Override
public void send(Message message, String destination) {
throw new UnsupportedOperationException();
}
@Override
public <T> void send(T payload, Map<String, Object> headers, String destination) {
throw new UnsupportedOperationException();
}
@Override
public Message<?> receive(String destination, long timeout, TimeUnit timeUnit) {
final JmsTemplate jmsTemplate = applicationContext.getBean(JmsTemplate.class);
final long originalReceiveTimeout = jmsTemplate.getReceiveTimeout();
try {
jmsTemplate.setReceiveTimeout(TimeUnit.MILLISECONDS.convert(timeout, timeUnit));
return (Message) new MessagingMessageConverter().fromMessage(jmsTemplate.receive(destination));
} catch (JMSException e) {
throw new RuntimeException(e);
} finally {
jmsTemplate.setReceiveTimeout(originalReceiveTimeout);
}
}
@Override
public Message<?> receive(String destination) {
return receive(destination, 3, TimeUnit.SECONDS);
}
}