esten der RabbitListener-Methode in der SpringBoot-A

Code

RabbitMQListener:

@Component
public class ServerThroughRabbitMQ implements ServerThroughAMQPBroker {
    private static final AtomicLong ID_COUNTER=new AtomicLong();
    private final long instanceId=ID_COUNTER.incrementAndGet();


    @Autowired
    public ServerThroughRabbitMQ( UserService userService,LoginService loginService....){
....
    }

    @Override
    @RabbitListener(queues = "#{registerQueue.name}")
    public String registerUserAndLogin(String json) {
       .....
    }

ServerConfig:

@Configuration
public class ServerConfig {
    @Value("${amqp.broker.exchange-name}")
    private String exchangeName;
    @Value("${amqp.broker.host}")
    private String ampqBrokerHost;
    @Value("${amqp.broker.quidco.queue.postfix}")
    private String quidcoQueuePostfix;
    @Value("${amqp.broker.quidco.queue.durability:true}")
    private boolean quidcoQueueDurability;
    @Value("${amqp.broker.quidco.queue.autodelete:false}")
    private boolean quidcoQueueAutodelete;

    private String registerAndLoginQuequName;


    @PostConstruct
    public void init() {
        registerAndLoginQuequName = REGISTER_AND_LOGIN_ROUTING_KEY + quidcoQueuePostfix;
    public String getRegisterAndLoginQueueName() {
        return registerAndLoginQuequName;
    }

    public String getLoginAndCheckBonusQueueName() {
        return loginAndCheckBonusQuequName;
    }



    @Bean
    public ConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory(ampqBrokerHost);
        return connectionFactory;
    }

    @Bean
    public AmqpAdmin amqpAdmin() {
        return new RabbitAdmin(connectionFactory());
    }

    @Bean
    public TopicExchange topic() {
        return new TopicExchange(exchangeName);
    }

    @Bean(name = "registerQueue")
    public Queue registerQueue() {
        return new Queue(registerAndLoginQuequName, quidcoQueueDurability, false, quidcoQueueAutodelete);
    }


    @Bean
    public Binding bindingRegisterAndLogin() {
        return BindingBuilder.bind(registerQueue()).to(topic()).with(REGISTER_AND_LOGIN_ROUTING_KEY);
    }

   }

TestConfig:

@EnableRabbit
@TestPropertySource("classpath:test.properties")
public class ServerThroughAMQPBrokerRabbitMQIntegrationTestConfig {
    private final ExecutorService=Executors.newCachedThreadPool();
    private LoginService loginServiceMock=mock(LoginService.class);
    private UserService userServiceMock =mock(UserService.class);

    @Bean
    public ExecutorService executor() {
        return executorService;
    }

    @Bean
    public LoginService getLoginServiceMock() {
        return loginServiceMock;
    }

    @Bean
    public UserService getUserService() {
        return userServiceMock;
    }

    @Bean
    @Autowired
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setMaxConcurrentConsumers(5);
        return factory;
    }

    @Bean
    @Autowired
    public RabbitTemplate getRabbitTemplate(ConnectionFactory connectionFactory) {
        final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        return rabbitTemplate;
    }

    @Bean
    public ServerThroughRabbitMQ getServerThroughRabbitMQ() {
        return new ServerThroughRabbitMQ(userServiceMock, loginServiceMock,...);
    }

}

Integrationstests:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes ={ServerConfig.class,ServerThroughAMQPBrokerRabbitMQIntegrationTestConfig.class})
@Category({IntegrationTest.class})
@TestPropertySource("classpath:test.properties")
public class ServerThroughAMQPBrokerRabbitMQIntegrationTest {
    final private ObjectMapper jackson = new ObjectMapper();
    @Autowired
    private ExecutorService executor;

    @Autowired
    private ServerThroughRabbitMQ serverThroughRabbitMQ;

    @Autowired
    private RabbitTemplate template;

    @Autowired
    private TopicExchange exchange;

    @Autowired
    UserService userService;

    @Autowired
    LoginService loginService;

    @Autowired
    private AmqpAdmin amqpAdmin;

    @Autowired
    private ServerConfig serverConfig;

    final String username = "username";
    final String email = "[email protected]";
    final Integer tcVersion=1;
    final int quidcoUserId = 1;
    final String jwt = ProcessLauncherForJwtPhpBuilderUnitWithCxtTest.EXPECTED_JWT;


    @Before
    public void cleanAfterOthersForMyself() {
        cleanTestQueues();
    }

    @After
    public void cleanAfterMyselfForOthers() {
        cleanTestQueues();
    }

    private void cleanTestQueues() {
        amqpAdmin.purgeQueue(serverConfig.getRegisterAndLoginQueueName(), false);
    }

    @Test
    @Category({SlowTest.class,IntegrationTest.class})
    public void testRegistrationAndLogin() throws TimeoutException {
        final Waiter waiter = new Waiter();

        when(userService.register(anyString(), anyString(), anyString())).thenReturn(...);
        when(loginService....()).thenReturn(...);


        executor.submit(() -> {
            final RegistrationRequest request = new RegistrationRequest(username, email,tcVersion);
            final String response;
            try {
                //@todo: converter to convert RegistrationRequest inside next method to json
                response = (String) template.convertSendAndReceive(exchange.getName(), REGISTER_AND_LOGIN_ROUTING_KEY.toString(), jackson.writeValueAsString(request));
                waiter.assertThat(response, not(isEmptyString()));

                final RegistrationResponse registrationResponse = jackson.readValue(response, RegistrationResponse.class);
                waiter.assertThat(...);
                waiter.assertThat(...);

            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            waiter.resume();
        });

        waiter.await(5, TimeUnit.SECONDS);
    }

}

Wenn ich diesen Test separat durchführe, funktioniert alles einwandfrei, aber wenn ich ihn mit anderen Tests durchführe, wird der verspottete ServerThroughRabbitMQ nicht verwendet, sodass einige Spring Caches die Verwendung des alten Kaninchen-Listeners erzwingen.

Ich habe versucht, es zu debuggen, und ich kann sehen, dass das richtige Bean für den Test automatisch verdrahtet wird, aber aus irgendeinem Grund verwendet der alte Listener (alte Bean-Feld-Instanz-ID = 1 neue verspottete Bean-Instanz-ID = 3) und der Test schlägt fehl (nicht sicher, wie) es ist möglich, also wenn es eine alte Bohne gibt, gehe ich davon aus, dass es eine Autowire-Ausnahme gibt.

Ich habe versucht, @DirtiesContext BEFORE_CLASS zu verwenden, hatte aber ein anderes Problem (sieheHie)

Antworten auf die Frage(2)

Ihre Antwort auf die Frage