if (this.messagingMessageConverter.method == null && amqpMessage != null) {
amqpMessage.getMessageProperties().setTargetMethod(this.handlerAdapter.getMethodFor(message.getPayload()));
It there anything I can do to avoid this situation?
To Reproduce
You need to start the tests which are located in the linked project.
Expected behavior
I would not expect the error since the methods are not loaded twice.
Sample
Starting the DifferentTypesDistributorListenerIntegrationTest or ManyCustomersWorkersSpyListenerIntegrationTest from the project led to the exception https://github.com/kstojanovski-novatec/spring-amqp-testing-issue.
Obviously, the original @RabbitHanlder method is loaded and the mocked one at the same time.
Might indeed be a case.
Not sure how to fix such a situation since you are indeed expecting only those stubs to be available for your testing.
Well, let's see if @RabbitListenerTest
can help you somehow: https://docs.spring.io/spring-amqp/reference/html/#test-harness.
Your project is too complex to give an immediate advice...
Hello Artem, thanks for the fast answer.
I saw the linked documentation and have also downloaded the four files from the GitHub repo:
org.springframework.amqp.rabbit.test.examples.ExampleRabbitListenerCaptureTest
org.springframework.amqp.rabbit.test.examples.ExampleRabbitListenerSpyAndCaptureTest
org.springframework.amqp.rabbit.test.examples.ExampleRabbitListenerSpyTest
org.springframework.amqp.rabbit.test.examples.TestRabbitTemplateTests
Only TestRabbitTemplateTests works well, but this kind of test I already have. I am interested in the other test where RabbitListenerTestHarness
is used.
Unfortunately the private RabbitListenerTestHarness harness;
is marked red with the message "Could not auto-wire. No beans of 'RabbitListenerTestHarness' type found." for the other three classes as well.
Then I downloaded the whole project Spring AMQP(spring-amqp-dist) and there the reference is also marked with the same message. I have tried to debug the tests and only TestRabbitTemplateTests could be debugged. The other tests are skipped. Should that be that way?
The harness
as red is just a flaw of an IDE.
That bean is provided by the framework and IDE does not have an ability to scan classpath for manually registered beans like it happens with this one via RabbitListenerTestBootstrap
.
Those tests does not pass for your because you don't have a RabbitMQ broker on the default host/port.
See that @RabbitAvailable
what all those tests are marked with.
In other words: the listener tests with mocks and spies still require a real RabbitMQ to interact with.
However you probably can combine both TestRabbitTemplate
and RabbitListenerTestHarness
.
spring-amqp/spring-rabbit/src/test/java/org/springframework/amqp/rabbit/annotation/EnableRabbitIntegrationTests.java
Lines 1979 to 1982
ee681bd
As stated, all methods are doubled up; in this case I get
java.lang.IllegalStateException: Failed to load ApplicationContext for [MergedContextConfiguration@41bb1f09 testClass = org.springframework.amqp.rabbit.annotation.EnableRabbitIntegrationTests, locations = [], classes = [org.springframework.amqp.rabbit.annotation.EnableRabbitIntegrationTests.EnableRabbitConfig], contextInitializerClasses = [], activeProfiles = [], propertySourceLocations = [], propertySourceProperties = ["spring.application.name=testConnectionName"], contextCustomizers = [], contextLoader = org.springframework.test.context.support.DelegatingSmartContextLoader, parent = null]
Caused by: java.lang.IllegalStateException: Only one @RabbitHandler can be marked 'isDefault', found: public java.lang.String org.springframework.amqp.rabbit.annotation.EnableRabbitIntegrationTests$MultiListenerBean$MockitoMock$GPAkOvLI.defaultHandler(java.lang.Object) and public java.lang.String org.springframework.amqp.rabbit.annotation.EnableRabbitIntegrationTests$MultiListenerBean.defaultHandler(java.lang.Object)
at org.springframework.util.Assert.state(Assert.java:97)
at org.springframework.amqp.rabbit.annotation.RabbitListenerAnnotationBeanPostProcessor.processMultiMethodListeners(RabbitListenerAnnotationBeanPostProcessor.java:368)
at org.springframework.amqp.rabbit.annotation.RabbitListenerAnnotationBeanPostProcessor.postProcessAfterInitialization(RabbitListenerAnnotationBeanPostProcessor.java:320)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:434)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1773)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:598)
... 85 more
Looks like we need to add code to the BPP to ignore methods from classes containing @MockitoMock
...
Spy method:
public java.lang.String org.springframework.amqp.rabbit.annotation.EnableRabbitIntegrationTests$MultiListenerBean$MockitoMock$m0IRDAeN.defaultHandler(java.lang.Object)
Real method:
public java.lang.String org.springframework.amqp.rabbit.annotation.EnableRabbitIntegrationTests$MultiListenerBean.defaultHandler(java.lang.Object)
Probably, yes; need to figure out what works (might need to filter out the non-mock methods) - but I am currently seeing another strange side-effect of making the bean a spy - when the queue name is anonymous, I am getting 2 containers/anonymous queues. If I name the queue, I only get one container. Very strange.
Resolves spring-projects#2456
When spying a `@RabbitListener` bean, duplicate methods are resolved as well
as duplicate class level `@RabbitListener` annotations.
**cherry-pick to 2.4.x** (will require instanceof polishing for Java 8)
Resolves #2456
When spying a `@RabbitListener` bean, duplicate methods are resolved as well
as duplicate class level `@RabbitListener` annotations.
**cherry-pick to 2.4.x** (will require instanceof polishing for Java 8)
Resolves #2456
When spying a `@RabbitListener` bean, duplicate methods are resolved as well
as duplicate class level `@RabbitListener` annotations.
**cherry-pick to 2.4.x** (will require instanceof polishing for Java 8)
Thanks for the work, Gary and Artem.
I wrote I found that issue in version 3.0.6, but it was the version of the pring-boot-starter-parent project. The version of the spring-amqp-dist project used there is 3.0.4, and of course, its modules, but the change is committed in the 3.0.5-SNAPSHOT.
When will the modification be part of the spring-boot-starter-amqp?
June 19, with Boot to follow a couple of days later.
https://github.com/spring-projects/spring-amqp/milestones
https://calendar.spring.io/
The framework is intended for use with Spring Framework 5.3.
However, this change was the only thing preventing it being used
with 5.2.
The framework is intended for use with Spring Framework 5.3.
However, this change was the only thing preventing it being used
with 5.2.