3

스프링 rabbitmq/amqp를 모의하는 방법 어떻게 자동 교환/대기열을 만들려고 시도하는 동안 스프링 부트 테스트에서 실패하지 않을까요?스프링 부트 테스트에서 spring amqp/rabbit를 모방하는 방법

내가 대기열 및 교환의 원인이됩니다 간단한 RabbitListener 자동차는 다음과 같이 생성 할 수 있습니다 감안할 때 :

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

    @Autowired 
    private ApplicationContext applicationContext; 

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

} 

는 것 같은, 간단한 봄 부팅 검사 중

@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) { 
     ... 
    } 
} 

을 실패 :

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) 

이 시험에서 나는 Rabbit/AMQP, 그렇다면 어떻게 토끼/AMQP 전체를 조롱 할 수 있습니까?

답변

2

특히 쉽지는 않지만 브로커를 사용할 수없는 경우 일반적으로 JUnit @Rule을 사용하여 테스트를 건너 뜁니다.

그러나 우리는 mock을 사용하는 많은 테스트를 수행하고 있지만 실제로 사용하기 위해서는 많은 수의 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

나는 어느 시점에서 비슷한 요구 사항을 가지고 있었고 메모리 AMQP 브로커를 제공하는 QPid를 조사했다. 그것은 당신이 AMQP 레벨에 머무를 것을 강요하고 가능한 한 작은 rabbitMq 특정 코드를 사용합니다.

그러나 실제로 다른 방법을 발견했습니다. 테스트 + 자동 삭제 값을 실행할 때 대기열 및 교환의 이름을 조정하여 더 이상 문제가 발생하지 않습니다. 테스트의 모든 대기열/교환 이름 뒤에는 테스트를 실행하는 계정의 사용자 이름이 붙습니다. 즉, 모든 사용자가 다른 사용자에게 영향을주지 않고 컴퓨터에서 테스트를 실행할 수 있습니다.

CI 파이프 라인에서도 여러 프로젝트가 동일한 교환/대기열을 사용할 수 있습니다. 프로젝트의 특정 값으로 구성되므로 프로젝트 2 개가 같은 시스템에서 동시에 같은 시스템에서 테스트를 실행하더라도 동일한 사용자는 메시지가 현재 테스트 외부에서 "유출"되지 않습니다.

메모리 브로커를 조롱하거나 스폰하는 것보다 관리가 훨씬 간단합니다.

1

우리 프로젝트에서는 로컬로 docker 컨테이너를 사용하여 RabbitMQ 인스턴스를 초기화합니다. 통합 테스트를 실행하기 위해 테스트 케이스의 시작 부분에 RabbitMQ 인스턴스를 시작하고 클린업 중에 종료합니다.

우리는 TestContainers를 사용하여이를 수행합니다. https://www.testcontainers.org/usage/dockerfile.html 및/또는 https://www.testcontainers.org/usage/docker_compose.html을 참조하십시오.

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 
}