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)