{"id":1560,"date":"2022-12-29T10:14:03","date_gmt":"2022-12-29T09:14:03","guid":{"rendered":"https:\/\/www.loicmathieu.fr\/wordpress\/?p=1560"},"modified":"2022-12-29T10:14:03","modified_gmt":"2022-12-29T09:14:03","slug":"quarkus-tip-tester-une-fonction-google-cloud","status":"publish","type":"post","link":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/quarkus-tip-tester-une-fonction-google-cloud\/","title":{"rendered":"Quarkus Tip: Testing a Google Cloud function"},"content":{"rendered":"<p>I recently contributed a <a href=\"https:\/\/github.com\/quarkusio\/quarkus\/pull\/27986\" rel=\"noopener\" target=\"_blank\">PR<\/a> to Quarkus that contains a testing framework for Google Cloud functions.<\/p>\n<p>Quarkus supports creating Google Cloud functions three different ways:<\/p>\n<ul><li>Using the Google Cloud API.<\/li>\n\n<li>Using a Quarkus HTTP extension: RESTEasy, Reactive routes, Servlet, Spring Web.<\/li>\n\n<li>Using Funqy, the cloud provider agnostic Quarkus function API.<\/li>\n<\/ul>\n<p>But until now, to test these functions, you had to package them and launch them locally via the function invoker provided by the Google SDK. The function invoker is a JAR you can download that can then be used to launch a function. Not very practical to use, and especially, does not allow to be used for automated unit tests.<\/p>\n<p>Functions using an HTTP extension of Quarkus could implement a unit test in a traditional way, but in this cas they would not use a function environment. So the test would not reproduce a function execution close to reality.<\/p>\n<p>With Quarkus 2.15, a framework for testing Google Cloud functions exists that allows to test a function via HTTP calls. This framework will use the function invoker and start it automatically when the test is launched. You can then use <a href=\"https:\/\/rest-assured.io\/\" rel=\"noopener\" target=\"_blank\">REST-assured<\/a> to test your function as you would for a standard Quarkus application.<\/p>\n<p>To use this test framework, you need to add the following Maven dependency:<\/p>\n<pre>\n\n    io.quarkus\n    quarkus-test-google-cloud-functions\n    test\n\n<\/pre>\n<h2>Testing a function that uses the Google Cloud Function API<\/h2>\n<p>The following function uses the Google Cloud Function API to implement an HTTP function that responds <em>&#8220;Hello World&#8221;<\/em>.<\/p>\n<pre>\n@ApplicationScoped \/\/ Needed for Quarkus to locate the function\npublic class HttpFunctionTest implements HttpFunction { \n    @Inject GreetingService greetingService; \n\n    @Override\n    public void service(HttpRequest httpRequest, HttpResponse httpResponse) throws Exception { \n        Writer writer = httpResponse.getWriter();\n        writer.write(greetingService.hello());\n    }\n}\n<\/pre>\n<p>The corresponding test will be a standard Quarkus test, annotated via <a>@QuarkusTest<\/code>code&gt;@QuarkusTest&lt;\/code<\/a>, but will use the <a>@WithFunction<\/code>code&gt;@WithFunction&lt;\/code<\/a> annotation that allows the function to be launched using the Google Cloud functions invoker. The <a>@WithFunction<\/code>code&gt;@WithFunction&lt;\/code<\/a> annotation takes as an attribute the type of the function to be launched, in this case <code>FunctionType.HTTP<\/code> because it is an HTTP function.<\/p>\n<pre>\n@QuarkusTest \n@WithFunction(FunctionType.HTTP) \nclass HttpFunctionTestCase {\n    @Test\n    public void test() {\n        when()\n                .get()\n                .then()\n                .statusCode(200)\n                .body(is(\"Hello World!\")); \n    }\n}\n<\/pre>\n<p>The test uses REST-assured to send an HTTP request with the GET method, and assert that the response has a status code 200 and contains the string <em>&#8220;Hello World&#8221;<\/em>.<\/p>\n<p>We can write the same type of test for a background function.<\/p>\n<p>Let&#8217;s take as an example a background function triggered from a Cloud Storage event:<\/p>\n<pre>\n@ApplicationScoped  \/\/ Needed for Quarkus to locate the function\npublic class BackgroundFunctionStorageTest implements BackgroundFunction { \n    @Override\n    public void accept(StorageEvent event, Context context) throws Exception { \n        System.out.println(\"Receive event: \" + event);\n    }\n\n    \/\/ The Cloud Storage event will be deserialized with this class\n    public static class StorageEvent { \n        public String name;\n    }\n}\n<\/pre>\n<p>It can be tested with the following code:<\/p>\n<pre>\n@QuarkusTest\n@WithFunction(FunctionType.BACKGROUND) \nclass BackgroundFunctionStorageTestCase {\n    @Test\n    public void test() {\n        given()\n                .body(\"{\\\"data\\\":{\\\"name\\\":\\\"hello.txt\\\"}}\") \n                .when()\n                .post()\n                .then()\n                .statusCode(200);\n    }\n}\n<\/pre>\n<p>Here, the test is of type <code>FunctionType.BACKGROUND<\/code>, and we send the event to the function via a POST request whose body is a JSON whose <code>data<\/code> attribute contains the event triggering the function.<\/p>\n<p>Cloud Events functions are also supported.<\/p>\n<p>More information in the guide <a href=\"https:\/\/quarkus.io\/version\/main\/guides\/gcp-functions\" rel=\"noopener\" target=\"_blank\">Quarkus Google Cloud Functions<\/a>.<\/p>\n<h2>Testing a function that uses Quarkus Funqy<\/h2>\n<p>It is possible to write a Google Cloud function reacting to a Cloud Storage event via the Funqy framework. Funqy provides a cloud provider agnostic API. To use Funqy, you need to write a Java method annotated with <a>@Funq<\/code>code&gt;@Funq&lt;\/code<\/a>, which takes the function&#8217;s trigger event as a parameter.<\/p>\n<pre>\npublic class GreetingFunctions {\n    @Funq \n    public void helloGCSWorld(StorageEvent storageEvent) {\n        String message = service.hello(\"world\");\n        System.out.println(storageEvent.name + \" - \" + message);\n    }\n}\n<\/pre>\n<p>To test this function, we&#8217;ll use the same code as for a function using the Google Cloud API, but we&#8217;ll configure the test framework for a function of type <code>FunctionType.FUNQY_BACKGROUND<\/code>.<\/p>\n<pre>\n@QuarkusTest \n@WithFunction(FunctionType.FUNQY_BACKGROUND) \nclass GreetingFunctionsStorageTest {\n    @Test\n    public void test() {\n        given()\n                .body(\"{\\\"data\\\":{\\\"name\\\":\\\"hello.txt\\\"}}\") \n                .when()\n                .post()\n                .then()\n                .statusCode(200);\n    }\n}\n<\/pre>\n<p>Here again, Cloud Events are also supported.<\/p>\n<p>More information in the guide <a href=\"https:\/\/quarkus.io\/version\/main\/guides\/funqy-gcp-functions\" rel=\"noopener\" target=\"_blank\">Quarkus Funqy Google Cloud Functions<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>I recently contributed a PR to Quarkus that contains a testing framework for Google Cloud functions. Quarkus supports creating Google Cloud functions three different ways: Using the Google Cloud API. Using a Quarkus HTTP extension: RESTEasy, Reactive routes, Servlet, Spring Web. Using Funqy, the cloud provider agnostic Quarkus function API. But until now, to test these functions, you had to package them and launch them locally via the function invoker provided by the Google SDK. The function invoker is a&#8230;<p class=\"read-more\"><a class=\"btn btn-default\" href=\"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/quarkus-tip-tester-une-fonction-google-cloud\/\"> Read More<span class=\"screen-reader-text\">  Read More<\/span><\/a><\/p><\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[9],"tags":[210,205,11,167],"class_list":["post-1560","post","type-post","status-publish","format-standard","hentry","category-informatique","tag-cloud-events","tag-google-cloud-functions","tag-java","tag-quarkus"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":1345,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/quarkus-et-les-google-cloud-functions\/","url_meta":{"origin":1560,"position":0},"title":"Quarkus and  the Google Cloud Functions","author":"admin","date":"Tuesday November  2nd, 2021","format":false,"excerpt":"Quarkus is a microservice framework designed for the cloud and the containers. It is designed to have a reduced memory usage and the shortest possible startup time. It is mainly based on standards (Jakarta EE, Eclipse MicroProfile, ...) and allows the use of mature and widespread Java libraries via its\u2026","rel":"","context":"In &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1440,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/google-cloud-functions-2nd-gen\/","url_meta":{"origin":1560,"position":1},"title":"Google Cloud Functions 2nd gen","author":"admin","date":"Tuesday March 29th, 2022","format":false,"excerpt":"Sorry, this entry is only available in Fran\u00e7ais.","rel":"","context":"In &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/category\/informatique\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/cloud-function-gen2-instances.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/cloud-function-gen2-instances.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/cloud-function-gen2-instances.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":2089,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/deploy-a-quarkus-application-in-cloud-run\/","url_meta":{"origin":1560,"position":2},"title":"Deploy a Quarkus application in Cloud Run","author":"admin","date":"Tuesday December 30th, 2025","format":false,"excerpt":"Quarkus is a microservice development framework designed for the cloud and containers. It is designed to have reduced memory usage and the shortest possible startup time. It is mainly based on standards (Jakarta EE, Eclipse MicroProfile, etc.) and allows the use of mature and widely used Java libraries via its\u2026","rel":"","context":"In &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1068,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/j-ai-teste-java-google-cloud-functions-aplha\/","url_meta":{"origin":1560,"position":3},"title":"(Fran\u00e7ais) J&#8217;ai test\u00e9 Java Google Cloud Functions Alpha","author":"admin","date":"Wednesday May  6th, 2020","format":false,"excerpt":"Sorry, this entry is only available in Fran\u00e7ais.","rel":"","context":"In &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1960,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/creer-un-chatbot-avec-google-gemini-vertex-ai-et-quarkus\/","url_meta":{"origin":1560,"position":4},"title":"Creating a chatbot with Google Gemini Vertex AI and Quarkus","author":"admin","date":"Friday June 27th, 2025","format":false,"excerpt":"I recently created a Quarkus extension that provides access to Google Vertex AI. In this article, I'm going to use this extension to create a chatbot. The first step is to create a Quarkus project containing the REST and Google Cloud Vertex AI extensions. Here are the extensions to add\u2026","rel":"","context":"In &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/category\/informatique\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/Capture-decran-du-2025-06-27-14-22-26-1024x376.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/Capture-decran-du-2025-06-27-14-22-26-1024x376.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/loicmathieu.fr\/wordpress\/wp-content\/uploads\/Capture-decran-du-2025-06-27-14-22-26-1024x376.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":1532,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/informatique\/tester-une-java-google-cloud-function\/","url_meta":{"origin":1560,"position":5},"title":"Testing a Java Google Cloud Function","author":"admin","date":"Tuesday October  4th, 2022","format":false,"excerpt":"Until recently, testing a Google Cloud Function written in Java could be done via the invoker provided by the Google Cloud Functions SDK but not via a unit test. But this changed recently! Let's take the following HTTP function as an example: public class HelloHttpFunction implements HttpFunction { @Override public\u2026","rel":"","context":"In &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/posts\/1560","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/comments?post=1560"}],"version-history":[{"count":8,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/posts\/1560\/revisions"}],"predecessor-version":[{"id":1599,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/posts\/1560\/revisions\/1599"}],"wp:attachment":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/media?parent=1560"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/categories?post=1560"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/wp-json\/wp\/v2\/tags?post=1560"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}