smallrye / smallrye-reactive-messaging

SmallRye Reactive Messaging
http://www.smallrye.io/smallrye-reactive-messaging/
Apache License 2.0
235 stars 176 forks source link

Cannot get Test going for InMemoryConnector #1799

Closed twinkybot closed 3 months ago

twinkybot commented 2 years ago

Hello

I could not get the InMemmoryConnector Example from the documentation https://smallrye.io/smallrye-reactive-messaging/smallrye-reactive-messaging/3.3/testing/testing.html running. Did I do something wrong or is the documentation not complete?

Steps to reprodice:

  1. Got a new Quarkus Project from https://smallrye.io/smallrye-reactive-messaging/3.18.0/getting-started/

  2. went to https://smallrye.io/smallrye-reactive-messaging/3.18.0/concepts/testing/ and followed steps there.

Which lead to:

java.lang.NullPointerException
    at foo.smallrye.MyTest.test(MyTest.java:41)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
    at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
    at ....

pointing to the InMemoryConnector, which imo cannot be injected.

  1. Thus I added @QuarkusTest which gives following output
java.lang.IllegalArgumentException: SRMSG18304: Unknown channel prices

    at io.smallrye.reactive.messaging.providers.connectors.InMemoryConnector.source(InMemoryConnector.java:181)
    at io.smallrye.reactive.messaging.providers.connectors.InMemoryConnector_Subclass.source$$superforward1(Unknown Source)
    at io.smallrye.reactive.messaging.providers.connectors.InMemoryConnector_Subclass$$function$$2.apply(Unknown Source)
    at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:53)
    at io.quarkus.smallrye.reactivemessaging.runtime.DuplicatedContextConnectorFactoryInterceptor.intercept(DuplicatedContextConnectorFactoryInterceptor.java:39)
    at io.quarkus.smallrye.reactivemessaging.runtime.DuplicatedContextConnectorFactoryInterceptor_Bean.intercept(Unknown Source)
    at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
    at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:40)
    at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
    at io.smallrye.reactive.messaging.providers.connectors.InMemoryConnector_Subclass.source(Unknown Source)
    at io.smallrye.reactive.messaging.providers.connectors.InMemoryConnector_ClientProxy.source(Unknown Source)
    at com.valtech.smallrye.MyTest.test(MyTest.java:42)....
  1. Then I added application.properties in src/test/resources
    mp.messaging.incoming.prices.connector=smallrye-in-memory
    mp.messaging.outgoing.processed-prices.connector=smallrye-in-memory

Well as I am new and totally confused what to do, I would very much appreciate some hints on how to get the test running. Maybe also in regards to the production class ReactiveMessagingExample which is provided in the Quarkus example.

ozangunalp commented 2 years ago

Could you add a reproducer project with your test?

twinkybot commented 2 years ago

https://github.com/twinkybot/SmallRye---InMemoryConnector

ozangunalp commented 2 years ago

You are right about adding the smallrye-in-memory to the test configuration. The switch to in-memory trick won't work for Quarkus tests.

Then you need to inject InMemoryConnector using a CDI qualifier,@Any should do it as there is only one of that type.

When using the injected connector, you need to get a source or sink from the in-memory connector for a channel that exists in your application. As far as I see "prices" does not exist in the application.

That leads me to say that we need to add more context to that example in the doc. That example is for an application like :

@Incoming("prices")
@Outgoing("processed-prices")
int process(int price) {
  return price;
}

So that you'd get the source of the incoming channel "prices" and send messages, and get the sink of the outgoing channel "processed-prices" to check that the channel produced messages.

Lastly, in the reproducer you sent, Outgoing and Incoming channels are both called "source". This means two streams will be linked in-memory, without using connector channels. You probably do not want that.

Hope this helps.

twinkybot commented 2 years ago

You are right about adding the smallrye-in-memory to the test configuration. The switch to in-memory trick won't work for Quarkus tests.

Then you need to inject InMemoryConnector using a CDI qualifier,@Any should do it as there is only one of that type.

@Incoming("prices")
@Outgoing("processed-prices")
int process(int price) {
  return price;
}

So that you'd get the source of the incoming channel "prices" and send messages, and get the sink of the outgoing channel "processed-prices" to check that the channel produced messages.

@ozangunalp Updated the project but I cannot get it to run, as the Connector is Null without the QuarkusTest annotation. Would you mind to change it so that it works, if you have time?

Lastly, in the reproducer you sent, Outgoing and Incoming channels are both called "source". This means two streams will be linked in-memory, without using connector channels. You probably do not want that.

And the naming 'source' of the channel is from another example. I removed it not to confuse issues.