apache / camel-quarkus

Apache Camel Quarkus
https://camel.apache.org
Apache License 2.0
252 stars 186 forks source link

Mocking endpoints in camel-quarkus tests #1981

Open rschlegel-cc opened 3 years ago

rschlegel-cc commented 3 years ago

camel-quarkus seems to be lacking a way for dealing with mocks for external endpoints in tests: we have Camel routes and use them in Quarkus. For testing, @QuarkusTest works really well and provides us with a CamelContext and everything else we need.

Things get tricky though when we want to mock external endpoints within existing routes, e.g. a call to an external HTTP service. This can be done using AdviceWithRouteBuilder and mockEndpointsAndSkip or more elaborate interceptors, but it modifies the CamelContext. Therefore tests are no longer independent and may fail or succeed depending on the execution order.

Using CamelTestSupport fixes this, as the CamelContext is recreated between tests but using a different CamelContext than the one created by QuarkusTest seems like a bad idea. It also seems to cause issues for certain routes, as the context might not contain everything that is needed, so I would assume that mixing CamelTestSupport and @QuarkusTest should be avoided.

To get a better idea of how this could be done I also looked at the Spring integration and saw that there are annotations that help with endpoint mocking and dealing with dirty contexts. Does something comparable (or plans for it) exist for camel-quarkus? If not, are there examples/best practices for dealing with scenarios like this? Thanks!

jamesnetherton commented 3 years ago

You can always stub out HTTP services with mock responses or use a library like WireMock. For other non-HTTP stuff testcontainers is pretty useful. That's the approach that this project has mostly used thus far.

The problem with replicating the CamelTestSupport stuff, is that it's not simple to have all of the functionality working in native mode.

rschlegel-cc commented 3 years ago

Thanks for the quick response, this helps quite a bit. And just to be absolutely sure that I did not misunderstand anything: CamelTestSupport should not be used together with camel-quarkus, right?

jamesnetherton commented 3 years ago

CamelTestSupport should not be used together with camel-quarkus, right?

Correct, it should not be used (IMO). There's no usage of it in this project, so we can't give any guarantees that it works properly. And like I mentioned, it wont work in native mode.

Maybe that'll change in the future, but for now I'd avoid it.

tstuber commented 3 years ago

I agree with @rschlegel-cc , it would be very helpful if there would be some more guidance for how to mock endpoints. We face many situations where we would like to build unit tests routes while mocking the actual endpoints.

ppalaga commented 3 years ago

I filed https://github.com/apache/camel-quarkus/issues/2679 to improve the testing page in our user guide.

neoxu999 commented 2 years ago

Hi @jamesnetherton , in most cases, we only need CamelTestSupport in JVM testing, mocking routes. For native, we can use integration test. Can you please provide some advice? How to move camel-test to camel-quarkus-test?

aldettinger commented 2 years ago

Hi @neoxu999, I think we are all very busy with other subjects those days but if you are able to invest time for a long effort to explore this path on your own, then here are few directions I could point.

Some users reported that they were able to @Inject a camel route in a @QuarkusTest. This apporach can't be the solution in my opinion and it had some limitations, for instance logging. But it could be a way to start playing with this subject.

Camel Quarkus is about mixing the best of Camel and Quarkus, so for tests I would naively say we would need a @CamelQuarkusTest junit 5 annotation that would somehow assemble the functionalities from @QuarkusTest and CamelTestSupport. Maybe, the first step would be to read/train with JUnit5 annotations, quarkus/cdi lifecycle, see how @QuarkusTest and CamelTestSupport have been implemented.

And on the long run, thinking about an approach that would allow @CamelQuarkusTest to be executed in native mode also would be killer feature. We would maybe need a way to serialize every test related objects from test process to the quarkus application under test process...

neoxu999 commented 2 years ago

Hi @aldettinger , thanks for your very detailed guides, including short and long plan. I will try to add @CamelQuarkusTest and make the JVM mode worked first.

neoxu999 commented 2 years ago

Hi @aldettinger, I checked the new extension guide. "Let others know that you work on the given extension by either creating a new issue or asking to assign an existing one to you." https://camel.apache.org/camel-quarkus/latest/contributor-guide/create-new-extension.html

May I get your permission to assign this task to me?

aldettinger commented 2 years ago

The root of this ticket is about being able to mock an endpoint. I guess experimenting with @CamelQuarkusTest that allow to mock an endpoint would be a good first experiment in scope of this ticket. We can refine later on if needed. Let me assign the ticket then.

ppalaga commented 2 years ago

Thanks the feedback and for taking the initiative, @neoxu999! As @aldettinger pointed out we are busy with other tasks and assisting with your contribution is all we can offer at this time.

neoxu999 commented 2 years ago

Thanks for your kind words @ppalaga! I will make it worked.

zhfeng commented 2 years ago

A simple hack way could be

@QuarkusTest
public class TransactedTest extends CamelTestSupport {
    @Inject
    CamelContext context;

    @Override
    protected CamelContext createCamelContext() throws Exception {
        return this.context;
    }
}

you can check it out on camel-test-demo.

aldettinger commented 2 years ago

Hey, great hack :)

It reminds me of an e-mail with Dennis Holunder posted in the community with the subject "Testing route in Camel Quarkus". I think it reported that it was working in JVM mode and there was just an issue with logging. Not sure it's still the case anyway.

My 2 cents, Alex

On Tue, Dec 14, 2021 at 10:23 AM Amos Feng @.***> wrote:

A simple hack way could be

@QuarkusTest public class TransactedTest extends CamelTestSupport { @Inject CamelContext context;

@Override
protected CamelContext createCamelContext() throws Exception {
    return this.context;
}

}

you can check it out on camel-test-demo https://github.com/zhfeng/camel-test-demo.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/apache/camel-quarkus/issues/1981#issuecomment-993339484, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFJABNOJ65KG5MBPRUEVVILUQ4EKTANCNFSM4THJUCVA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.