3

如何模擬春季rabbitmq/amqp,以便在嘗試自動創建交換/隊列時在Spring Boot Test期間不會失敗?如何在春季啓動測試中模擬彈簧amqp /兔子

鑑於我有一個簡單RabbitListener將導致隊列和交換被自動創建這樣的:

@Component 
@RabbitListener(bindings = { 
     @QueueBinding(
       value = @Queue(value = "myqueue", autoDelete = "true"), 
       exchange = @Exchange(value = "myexchange", autoDelete = "true", type = "direct"), 
       key = "mykey")} 
) 
@RabbitListenerCondition 
public class EventHandler { 
    @RabbitHandler 
    public void onEvent(Event event) { 
     ... 
    } 
} 

一個簡單的Spring引導檢測過程中,像這樣:

@ActiveProfiles("test") 
@RunWith(SpringRunner.class) 
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = { Application.class }) 

    @Autowired 
    private ApplicationContext applicationContext; 

    @Test 
    public void test() { 
     assertNotNull(applicationContext); 
    } 

} 

它會失敗與:

16:22:16.527 [SimpleAsyncTaskExecutor-1] ERROR o.s.a.r.l.SimpleMessageListenerContainer - Failed to check/redeclare auto-delete queue(s). 
org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused 
    at org.springframework.amqp.rabbit.support.RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:62) 
    at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:309) 

在這個測試中,我不在乎兔子/ AMQP,那麼我該如何嘲笑整個兔子/ AMQP呢?

回答

2

這不是特別容易,我們通常使用JUnit @Rule跳過測試,如果經紀人不可用。但是,我們確實有很多使用mock的測試,但您必須瞭解很多Spring AMQP內部使用它們的情況。您可以瀏覽project itself中的測試用例。

有一次,我確實嘗試寫一個模擬經紀人,但最終工作太多了。

+0

奇怪的是,它用於1.5.6 - 我只需要像這樣配置一個Bean:Mockito.mock(AmqpTemplate.class) - 但現在1.6。1這不再工作:( – domi

+0

如果我是正確的,這也意味着我將無法使用任何SpringBoot測試用例與一個完整的容器,當我有這樣的配置:( – domi

+0

嘲笑模板很容易;這是嘲弄經紀人的迴應(確認,退貨,交付),涉及更多,解釋爲「不再有效」 - 「AmqpTemplate」是一個簡單的「界面」; 1.6中沒有任何東西會改變它的嘲諷能力。對於'@ RabbitListener',你將不得不模擬一個監聽器容器 –

1

我在某個時間點有類似的需求,看着QPid,它提供了一個內存AMQP代理。它迫使你保持在AMQP級別,並儘可能少使用rabbitMq特定代碼。

但是我實際上找到了另一種方法:通過在運行測試+自動刪除值時調整隊列和交換的名稱,我們不再存在這個問題。測試中的所有隊列/交換名稱後綴爲(運行測試的帳戶的)用戶名,這意味着每個人都可以在其計算機上運行測試而不會影響其他人。

即使在我們的CI管道中,有些項目可能會使用相同的交換/隊列:我們將測試中的值配置爲項目特定的,這樣即使兩個項目同時在同一臺機器上運行測試同一用戶,消息不會在當前測試之外「泄漏」。

這最終比管理內存代理模擬或產生內存要簡單得多。

1

不知道這是否有幫助,但我有同樣的問題。所以,我只是在RabbitAdmin上使用了@MockBean,並使用了不同的配置文件,並且我沒有得到相同的連接問題。測試通過。

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) 
@RunWith(SpringRunner.class) 
@ActiveProfiles("my-test") 
public class ServiceTests { 

@Autowired 
private DummyService unitUnderTest; 

@MockBean 
private RabbitAdmin rabbitAdmin; 

// lots of tests which do not need Spring to Create a RabbitAdmin Bean 
}