我正在尝试为连接到RabbitMQ代理的Scala / Java应用程序创建集成测试。为了达到这个目的,我想要一个能够在每次测试之前开始和停止的AMQP的嵌入式代理。最初我尝试将ActiveMQ作为嵌入式代理引入AMQP,但是应用程序使用RabbitMQ只能说AMQP版本0.9.3而ActiveMQ需要AMQP版本1.0。
我可以用另一个嵌入式代理代替ActiveMQ吗?
答案 0 :(得分:13)
完全内存解决方案。根据需要替换spring.*
属性。
<dependency>
<groupId>org.apache.qpid</groupId>
<artifactId>qpid-broker</artifactId>
<version>6.1.1</version>
<scope>test</scope>
</dependency>
public class EmbeddedBroker {
public void start() {
Broker broker = new Broker();
BrokerOptions brokerOptions = new BrokerOptions();
brokerOptions.setConfigProperty("qpid.amqp_port", environment.getProperty("spring.rabbitmq.port"));
brokerOptions.setConfigProperty("qpid.broker.defaultPreferenceStoreAttributes", "{\"type\": \"Noop\"}");
brokerOptions.setConfigProperty("qpid.vhost", environment.getProperty("spring.rabbitmq.virtual-host"));
brokerOptions.setConfigurationStoreType("Memory");
brokerOptions.setStartupLoggedToSystemOut(false);
broker.startup(brokerOptions);
}
}
添加initial-config.json
作为资源:
{
"name": "Embedded Test Broker",
"modelVersion": "6.1",
"authenticationproviders" : [{
"name": "password",
"type": "Plain",
"secureOnlyMechanisms": [],
"users": [{"name": "guest", "password": "guest", "type": "managed"}]
}],
"ports": [{
"name": "AMQP",
"port": "${qpid.amqp_port}",
"authenticationProvider": "password",
"protocols": [ "AMQP_0_9_1" ],
"transports": [ "TCP" ],
"virtualhostaliases": [{
"name": "${qpid.vhost}",
"type": "nameAlias"
}]
}],
"virtualhostnodes" : [{
"name": "${qpid.vhost}",
"type": "Memory",
"virtualHostInitialConfiguration": "{ \"type\": \"Memory\" }"
}]
}
答案 1 :(得分:8)
我已经开发了一个包装器,用于下载,提取,启动和管理RabbitMQ,因此它可以像任何JVM项目控制的嵌入式服务一样工作。
检查出来:https://github.com/AlejandroRivera/embedded-rabbitmq
它很简单:
EmbeddedRabbitMqConfig config = new EmbeddedRabbitMqConfig.Builder()
.version(PredefinedVersion.V3_5_7)
.build();
EmbeddedRabbitMq rabbitMq = new EmbeddedRabbitMq(config);
rabbitMq.start();
...
rabbitMq.stop();
适用于Linux,Mac和Windows。
答案 2 :(得分:6)
以下是OrangeDog提出的适用于Qpid Broker 7.x的解决方案,灵感来自here:
添加qpid 7.x作为测试依赖项。在7.x中,这些已经在核心+插件中分离,具体取决于您的需要。对于RabbitMQ AMQP版本,您需要qpid-broker-plugins-amqp-0-8-protocol
并且要在内存中运行(足以进行集成测试),请使用qpid-broker-plugins-memory-store
。
pom.xml
:
...
<properties>
...
<qpid-broker.version>7.0.2</qpid-broker.version>
</properties>
<dependencies>
...
<dependency>
<groupId>org.apache.qpid</groupId>
<artifactId>qpid-broker-core</artifactId>
<version>${qpid-broker.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.qpid</groupId>
<artifactId>qpid-broker-plugins-amqp-0-8-protocol</artifactId>
<version>${qpid-broker.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.qpid</groupId>
<artifactId>qpid-broker-plugins-memory-store</artifactId>
<version>${qpid-broker.version}</version>
<scope>test</scope>
</dependency>
</dependecies>
...
使用硬编码的用户/密码添加代理配置,并将默认的内存虚拟主机映射到默认端口(5672):
qpid-config.json
:
{
"name": "EmbeddedBroker",
"modelVersion": "7.0",
"authenticationproviders": [
{
"name": "password",
"type": "Plain",
"secureOnlyMechanisms": [],
"users": [{"name": "guest", "password": "guest", "type": "managed"}]
}
],
"ports": [
{
"name": "AMQP",
"port": "${qpid.amqp_port}",
"authenticationProvider": "password",
"virtualhostaliases": [
{
"name": "defaultAlias",
"type": "defaultAlias"
}
]
}
],
"virtualhostnodes": [
{
"name": "default",
"defaultVirtualHostNode": "true",
"type": "Memory",
"virtualHostInitialConfiguration": "{\"type\": \"Memory\" }"
}
]
}
定义junit ExternalResource
并声明为ClassRule
(或在您的IT @BeforeClass
和@AfterClass
方法中启动和关闭嵌入式代理:
EmbeddedAMQPBroker.java
:
public class EmbeddedAMQPBroker extends ExternalResource {
private final SystemLauncher broker = new SystemLauncher();
@Override
protected void before() throws Throwable {
startQpidBroker();
//createExchange();
}
@Override
protected void after() {
broker.shutdown();
}
private void startQpidBroker() throws Exception {
Map<String, Object> attributes = new HashMap<>();
attributes.put("type", "Memory");
attributes.put("initialConfigurationLocation", findResourcePath("qpid-config.json"));
broker.startup(attributes);
}
private String findResourcePath(final String fileName) {
return EmbeddedAMQPBroker.class.getClassLoader().getResource(fileName).toExternalForm();
}
}
集成测试:
public class MessagingIT{
@ClassRule
public static EmbeddedAMQPBroker embeddedAMQPBroker = new EmbeddedAMQPBroker();
...
}
答案 3 :(得分:3)
我不知道任何嵌入式RabbitMQ服务器,所以我认为你有几个选项可以解决这个问题:
您的RabbitMQ服务器不需要存在于您的CI服务器上,您可以启动一个新的服务器,即您的CI rabbitmq服务器。如果你不能自己带一个,你可以看看CloudAMQP。今天的免费套餐提供:每月1M条消息,20条并发连接,100条队列,10,000条排队消息。可能足够您的CI流程。
如果您的测试仅针对RabbitMQ进行单元测试,您可以模拟您的RabbitMQ消息生成。这就是我们在一些单元测试中所做的。我们只是检查一个特定的操作使方法调用产生一个特定的消息,但我们嘲笑它,所以我们实际上不发布消息。然后,我们通过使用我们创建的特定消息显式调用使用者方法来测试每个使用者。
答案 4 :(得分:2)
您可以尝试Apache QPid Java broker。这可以用作嵌入式代理。
Scala中的设置在另一个SO问题中进行了描述 - Example of standalone Apache Qpid (amqp) Junit Test