提问者:小点点

Spring Cloud合约-没有名为“验证”的bean可用


我有一个运行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'

共2个答案

匿名用户

如果您在类路径上同时具有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);
    }
}