Quarkus Insights #1: Tests
Monday we went live with Quarkus Insights #1: Testing with Georgios showing and talking about all things Testing. Especially showing the new Mockito integration and examples of TestContainer usage.
The code he shows are at https://github.com/geoand/quarkus-test-demo and below are a transcript (Thanks Markus!).
On Tusday May 12th 11:15 CEST / 14:45 IST / 05:15 EST we will do Quarkus Insights episode #2: quarkus:dev & command mode with Stuart Douglas!
This is at a more European/APAC time friendly slot - anyone that shows up from United states gets a shout out for being up way too early!
We will talk about how to use
quarkus:dev and the new command mode - knowing Stuart we will also get to digg deep into the internals of Quarkus.
Do add questions to the youtube video already or show up on the live show and ask away - we will cover as much as we can!
To join current live show or see the next one scheduled bookmark this link: https://youtube.com/quarkusio/live
Below is a transcription of the episode.
Kudos to Markus Eisele for making this happen!
Emmanuel: Quarkus Inside number one. Test.
Well, Hello everyone. And we’re cheap on the budget right now.
Alright, so I’m not alone in this madness. Welcome to this new episode of Quarkus Inside. It’s an official one, in the sense that it’s not a meta subject. We’re gonna have real conversations around test today and to have conversation here. I do have Max, my colegue and partner in crime, but also Georgios which has been a massive contributor to Quarkus, being left and right, so maybe Georgios, do you wanna introduce yourself?
Georgios: Yeah, thanks, thanks, you Emmanuel.
Yeah, my name is Georgios or George as it would be spelled in English. I’ve been with Red Hat for a couple of years, but my life really changed when the great folks that started Quarkus really announced it internally, and I had a massive way. Oh man, I gotta jump on to this thing. It’s beyond what I could ever imagine. So yeah, I started contributing nesting for spring stuff and then just took it from there basically. Now trying to do, like you said, things left or right.
Emmanuel: So I guess to… I’ll speak in the name of the great folks of Quarkus it’s like "Thanks God, Georgios is here", 'cause you jump on every trouble we have. It’s been a great, great experience.
Georgios: Thank you thinking very much.
Emmanuel: Alright, so, Max, do you wanna say a few things before we… We go to the…
Max: So, yes, a few things. I hopefully should have fixed my sound now and Emmanuel should have stopped sending out my sound twice.
Max: That’s less weird.
And other thing is that we actually, over the weekends, our channel actually went from around 8-900 to, now past a thousand that’s cool.
Yeah, so we need to do this. And over the weekend we had another thing: Tim Fox started thread a about how you pronounced Quarkus and since it’s a long, a long thread. So I’m just wondering how you guys pronouncing it. So mine is Quarkus.
What’s yours Emmanuel?
Emmanuel: To me it’s like, "Spartakus" or it’s Quarkus. But I’m Frensh so who knows.
Georgios: And I was on a, I say, Quarkus.
Emmanuel: Yeah, 1.02k you guys send that? And that’s the Tim Fox threat for the conversation. And I love when British talks to British about pronunciation, or can… Yeah, I always just love it.
Max: It was tomato tomato, data, data. Yeah, the whole thing. Anyway, I accept all pronunciation of Quarkus, it’s fine.
Emmanuel: Yes, it’s. You know the worst was Cylon. Exactly this one was like really difficult so we did better for Quarkus… Alright.
Max: The last thing I had was: So we published an article, like a blog with the video, that we did last time and we added the transcription in there, which I think works pretty nice, like last time, is we didn’t talk about technical hopefully today, George gonna tell us all good things you have to know about testing. So it might be more useful. If anyone wanna say that’s useful or we should keep doing that! All done by Markus Eisele. He volunteered to do it. So pretty awesome. It’s also actually the sub-titles.
So if you go and you don’t standing neither Emmanuel’s French English or my mumbling Danish. There’s now sub-titles!
Emmanuel: Transcripts here and subtitles in the video itself you mean?
Max: Yeah, so if you go to the videos, there is one whatever Google recognize which I kept there just for entertainment value, the one that I…
Emmanuel: Where do I go, I guess, videos…
Max: Yeah you click on the video and then you see the… the CC, in the corner. So you just dump in the text and then Google figure out where the timestamps are. I was pretty impressed it’s… Is it good? Would be good if the time spent… is something that people like to for that was…
Emmanuel: Anyway, that was the production of things here. Receiving our stuff are… Yeah, alright, so we’re ready. We can share the screen of Georgios, but today we’re going to talk about tests in Quarkus. So Is a Java framework, so I just use JUnit and off I go right? Or is it a bit more complicated?
What do you guys think?
Georgios: Well, like all things in life. I think it’s a little more complicated but not too much, not too much. If you’re a regular enterprise Java developer no problem at all, it usesall the stuff you already know. So yeah, you’ll have to use a couple of new annotations or whatever, but you just pick up the regular libraries, you already know we’ll show QuarKito we’ll show WireMock, AssertJ. So all good, you just have to understand how these fit in with the Quarkus ecosystem, but other that, all good.
Emmanuel: Okay, by the way. So here, it’s not about Test, but John says, "Hey how do you pronouce pronouciation?" ;]
So it says "prononciation" in French, so there you go to not… But, more seriously, if you have questions, what we are having conversation with Georgios around test, so we’re gonna pretend we’re having… Well, not that pretending actually, but we’re gonna have questions to Georgios and ask questions, but if you do have questions on your own, just send them to the comments and will push a few selected ones, and then you know, ask Georges for the answer hopefully.
So something I wanted to say is if you want a plain unit test with like no dependencies with the infrastrcuture you just can go and use your unit or whatever is your preferred framework. I think we have to say we did settle on JUnit 5, as the default framework to do testing, so we recommend you keep that for Quarkus, but then Quarkus has this interesting model where it’s fast enough or really fast to get started, to start itself therefore we can run the whole application in each of your tests, and then you can run in real life situation, right, is that correct?
Emmanuel: You want me to share your screen. So, you show that a little bit or?
Georgios: Yeah, whatever you think.
Emmanuel: Yeah, sure, let’s get started with it. Unless you guys have some more introduction on the testing or would you…
Max: No, sounds good to me!
Georgios: No, I’m good.
Emmanuel: So there you go, Yeah, I do Skype. So this is a Quarkus app, right?
Georgios: Yes, this is a Quarkus application that I generated using my Maven tooling, so I haven’t changed anything, just created a Quarkus application opened it in IntelliJ which I’m using throughout this present. [unaudible, scattered] So you wanna talk about what these two-generated tests are?
Emmanuel: Yeah, let’s start with the first one.
Georgios: Yeah, got it, so, okay, cool. So like Emmanuel said, when we use JUnit 5 with Quarkus, our integration with Quarkus, what it does is that it starts Quarkus itself. The whole Quarkus application. And we envision like you run actual, hit the actual endpoints that your application uses, that’s not the only thing you can do. Of course, you can do a whole bunch of other stuff. But that’s like the main way we see it being used. So here you see the Quarkus test is our integration point with JUnit 5, and that’s all you need to do just to start your Quarkus application inside the test. And here is like you just write your regular test. We’re using REST-assured here, with Quarkus supports out of the box, so you’re hitting the Hallo endpoint expecting it…
Emmanuel: You don’t have to, by the way, but I think we integrate right away, the port and host that the Quarkus app is running with REST-assured. It’s like a total transparent experience for you.
Georgios: Exactly, yeah, if we didn’t integrate out of the box, you would have to select here. You have to do port, like 8081 or whatever. Yeah, we do that out of the box. So it’s the experiences with no friction at all.
Emmanuel: Oh, speaking of… So you put 8081 for a reason. So the default port, in Quarkus is 8080, so that’s how we start.
So historically, from WildFly and even before… But for test we’ve decided to bump the port to one, so that you can run your test and while having your life application running, right?
Georgios: Yeah exactly, so exactly our default port for running the regular applications is 8080 but you bring your test 8081. so, we envision… You can do multiple things in… also the dev mode runs in 8080, so you can have your dev mode running and then your test like running separately. But just the way we have to that to make things.
Emmanuel: Can I change it?
Georgios: Yes, absolutely. You go here to Quarkus, well, this my… IntelliJ Ultimate doesn’t have a property completion yet.
I know Max is working on it but there’s also a community plug-in, but I haven’t installed it yet… But anyway, http port would be like 8080, say 9090 for the regular one.
Max: Just get to clarify: IntelliJ, if you install the community Quarkus plug-in you should have…
Georgios: Yeah, yeah, yeah, exactly. I haven’t installed that, but IntelliJ Ultimate out-of-the-box doesn’t have that, but I haven’t installed it so, if I wanted to change the port, Like let’s say 8082, I would just do this set Quarkus http.test-port. So like Emmanuel like to say a lot and I think it’s a great decision is that, everything in Quarkus is configured through the application properties so a whole bunch of our frameworks and libraries that we use are controlled in this manner. So you just have to learn a set of properties and you can figure out all the properties, like You go Quarkus… Even if I.
I don’t have the IDE integration, but if I go to http reference on our web page we can see what all the properties are or not here, maybe like Quarkus testing, I usually just open the source code. So anyway, I’m not sure exactly where they are now. You remember that be great but usually the… The properties are right on the site, so you can see exactly what you’re actually…
Emmanuel: You can to me, let me take the… One thing I liked and have to admit I went really kicking and screaming for that, but what I thought was really the best solution was for each guide to have the list of properties for it. So if you go to… Sorry my network is suffering a bit apparently, so if I go to configuring data sources, here at some point, you see, here’s how I configure the data source and you might even have the complete list somewhere, I think, towards the end?
Yeah, there you go, you get a full page, here and we did two things. So one is this list here is actually generated from the list of properties we have in each of the in this specific extension. And you can filter stuff here. So if I am only looking for health check, then it doesn’t work.
Don’t know what’s going on… Yeah, they go. So you got the filtering of the list of properties, so that’s useful too, if you got a big list of properties, but another one that is usedful is if you go back to quarkus.io/guides, here the second one. So Hey, the first one is, "Hey how do I continue my app? But the second one is, "Give me all of the possible quotes configurations ever".
And here you’ve got the massive list of properties, and you can really quick search something. So yeah, if I look for, I don’t know, SQL because I want the Hibernate way to find things where… I guess I should have used… you that there’s a bit too many here, but I should be able to find somehow fast enough. The… There you go Hibernate ORM, then you see how do I get the logs?
So I log creator would have been been better.
So it’s a nice way to get all of the properties and filter them out very quickly. And I was against that. But since we have automated it, we said, Hey, why not? And it was actually, it is a very good, very good solution. So, back to Georgios now…
Georgios: Yeah, thanks for that. Yeah, I was looking for those. But yeah, that’s exactly, yeah. How we envison people would find it more with the IDE integration, like VS code has it out of box and stuff like that.
So let’s go in like run a first test, right? So for my need it should just work. I’ll just hit it right here.
And what this will do is it will start the Quarkus application and will actually perform an http request, against the Hello endpoint. So if I go and change this to below here, then obviously my test fail, or then again, my test will fail because I expected "hello", and that’s it for the REST-assured stuff. So, REST-assured stuff integration out of the box.
This is a regular JVM application. When we write a Quarkus test, now we have another sort of test which we call the "native image test". Now, what this does is that it gives you the ability to build the GraalVM native image and run tests against that. So it’s like one… Just one quick here, I can run and I can build the test that and both sorry. Yeah.
I haven’t configured IntelliJ to properly find everything here, but if I do mvn -verify -pNative what it will do after running the reading resource test it’ll run this test with Maven fail-safe if it’s an actual integration test and build the GraalVM native image as we’re seeing here.
And once it builds that it’ll start it and execute in this case it’ll execute the same rest endpoint; the same http request against the rest endpoint of the native image.
Emmanuel: Yeah, so if you’re unsure about the nature image that’s how you would do your extra smoke tests to make sure the native image is not doing something funky compared to the actual Java code.
Georgios: Exactly… Yeah, that’s exactly… We see it as a black-box testing thing, where you can only test the parts of the application that are available from the outside, like http or messaging, or anything like that.
Emmanuel: By the way you said you forgot to configure your stuff in IntelliJ. I think it’s to export a property, which is GraalVM home, something like that…
Georgios: Yeah, exactly.
Emmanuel: So you edit your test and you set an environment viable, which is GraalVM home, which will point to the native image generator, forgot the name of it.
Georgios: Native yeah, native image, yeah. So yeah, exactly… I configure it here, and then I would figure it out, and then everything would just work, but I didn’t do that now, but okay.
Emmanuel: He we got one question from __. Let’s try to extract something out of it so "Guys, please make a guide to test driven development and post from controller, service and repos in these video. Thank you for helping me, I have coffee on my POM, but inject more kind of return some error. I’m not sure what inject mock. Oh, I guess we gonna go and address the whole mock as a bit later. Maybe that would be a good time to dive into this.
Georgios: Sure, sure, yeah, sounds good.
Max: I do think the point here is the POST part. I think the point here is the post part, I assume, 'cause the GET part is easy, it’s more the post, the to…
Georgios: Yeah, well, the post flow isn’t anything specific to Quarkus just you would use your rest assured, you just configure rest assured the rest assured test to do whatever it needs to do with POST.
Also, we can do that. Yeah, we can do that later but another thing we should mention is that our quick starts have most of this stuff implemented, already. So looking at the Quarkus quick starts is which I’ll pull up right here is a great way to see all the stuff that we envision as the proper way of doing things or have a lot of examples. So here it is: quarkus.io. quick starts, we have all the quite starts here. If I go for "POST" I’m pretty sure let’s find something.
Yeah, so it would be here, like the validation right here you can see an example of how you would do POST. So it’s here like you, it’s just rest assured there’s nothing Quarkus specific to this. But yeah, we can try it out.
So how, how we move on to something that…
Emmanuel: So we got one question from Recardo… Is there a way, as the test runs the Quarkus app to automate the bootstrap of dependent system, which I think is gonna be a nice connection to test containers and how you can integrate it. So whenever you wanna jump on that we can…
Georgios: Yeah, not exactly sure what Recardo means here, 'cause it could mean various things in the Quarkus space.
Emmanuel: I suppose it’s not a dependent system of the internal of the application here, we will see how you do mock, which would be a way to walk around that, but I assume he wants to start an external database.
Georgios: Yeah, yeah, We’ll show that. Yeah, we’ll definitely show that. That’s one of the points that we really want to cover test containers.
So let’s start with something that we really hear a lot.
A lot of people wanna mock the REST client because we wanna start using REST client and then start testing it.
REST client is like super useful because every micro-service has to do http requests sooner or later, so anybody ends up using the REST client.
Let’s go ahead and start with creating an example. REST client, we wanna do. I wanna have a… I’m gonna hit an external country service, so the first thing I wanna do is create a country let’s say, DTO, I give it two fields "name" and "capital".
Okay, let me just go ahead and use JSON B, so import as we support JSON, B and Jackson. Both for marshelling and marshelling Jason, I’m just gonna use this on here just for no particular reason. So let’s set up… What can I do?
Max: You could have done that with add-extension?
Georgios: Yes I could have done mvn add-extension. But since I’m already in the IDE, I just copy&paste to here.
So, I’m just doing…
Emmanuel: It just means that adding an extension is literally adding something in the POM, so that’s…
Georgios: Yes, no magic, yeah. So we have tooling to automate this.
So everybody’s work flow is different. My workflow is so for me it’s just easier to copy paste into pom.xml.
Other people couldn’t do it a lot differently.
Emmanuel: Yeah, I used to develop with X. so do you then…
Georgios: So, no I’ve always been an IntelliJ fan. So, we set up our DTO and now it’s actually set up with the REST client would look like. So, it’s a country services, so the REST client is declared. The whole idea is that you declare an interface, and then Quarkus will automatically implement that interface for you in order by generating a code that will use a http request. So what we’re gonna do here we’re gonna hit an external - we’re gonna try to use an external service. I’m gonna use this REST country service, right?
__ And I’m just gonna use one end point, which is the name endpoint which, as you can see here, what I wanna hit is this REST v2 main name, so that’s what I’m gonna try to set up here.
Country import… get by name… String name… Yeah, this will be a GET as I can see here. Well, it doesn’t say it, but it is a GET anyway and return produces an application JSON and the path will see the whole path for the country for the version of the country service. I’m using under v2 as we see here.
And the path for _ class is a name as _ So that sets it up. I’m just gonna copy paste the URL. So like we said earlier, we can figure a lot of things through application properties. And since I wanna type this whole thing here, this is what you would configure. So basically when you’re building a REST client, Quarkus is building a REST client it needs to know what the base URL is and this is how we set the base URL so this is the name of the class.
Oh, I and you said this is the suffix of the property that we use in order to configure the base URL. So base URL is __.
And now, how we’re gonna call, how we’re gonna supposed to use this so; Well, I’m just gonna expose this as a rest API, so run building anything with business logic here, we just gonna fill the rest endpoint that will delegate to hitting don’t get to the REST client, to hit the rest endpoint of __.
I don’t know Emmanuel, I don’t know what your thoughts are on what this is supposed to call in the Spring world. We call this controller. I guess, here, in Quarkus we’ve been using resource, but I know talking to Stephane he didn’t really like that name. So I know what you guys think what your opinion is.
Emmanuel: I don’t have opinions really so.
Georgios: How about you, Max?
Max: A control for me, it’s something I’d used.
Emmanuel: Yeah, I think, I’d use controller in my Play days.
Georgios: Oh, okay, so that’s how Play did it, well, Okay. Here we go. So we’re injecting the country service, the interface into the… We call it a resource here but when a partner is created at the REST client CDI qualifier. So when we’re injecting we have to use that qualifyer as well and this is done, because you might wanna create your own but in this case, we’re just using the qualifier to disambiquate if there are multiple services, multiple implementations of the country service. So I’m just gonna copy this here, and go and let’s see, this is GET… And I’ll say, path name - name and __.
Okay, so now what I’ve done to set up a resource which will hit the REST client, but now I wanna test it, right, so I just… I’ll create a new test.
I’ll say regular country resource test is gonna be a Quarkus test. And I’m just gonna copy this here.
So I basically have to do similar things is test _. So _.
Georgios: No we’re out of the IMF.
Emmanuel: Well everybody is in at some point.
Georgios: Yeah, I agree _ away that behind us. So now what I’m gonna do here I’m gonna try and show what I expect it to return. So this is just standard rest assured syntax, so this will be the size here I expected to be one because when I hit the REST service it’ll give me one only. If I added like _ return a lot more results, and I’ll go and I’ll say, the first result name is, the name is "Greece"
Max: __ path, right?
Georgios: Yes, yes, it’s __. Rest assured uses Jetty.
Emmanuel: Let me ask a question to the readers "Does anybody know why we started the video with the music from Star Wars? You can carry on on a… Somebody picks that up.
Georgios: Okay, so now I’m starting the test inside my browser… Ah, we made a mistake here and I think I made a mistake.
Did I not add JSON on the REST client? JSON V could not find MessageBodyWriter… ah… Obviously I made a mistake. Produces then… Yeah, I think it’s also I made a mistake here. I didn’t… You gotta should have caught that returning Jason.
Max: What was the error?
Georgios: The error was that it told me that it couldn’t return an octet stream because I didn’t have his produces. So by default it is using ocetet stream and it couldn’t figure that out.
Emmanuel: May the fourth, so that’s why we had the sound…
Georgios: Oh, so I made another mistake, I didn’t add getters here.
Emmanuel: While you figure that out, there was a question for Antony. "Hey gang, I can’t find a saved update __ in Panache TTbase what’s wrong?"
So it’s a joke because Antony is a long time contributor and team member of the Hibernate before he went into the darker side of support, and then later training and certification. But it is a very good question and it’s a more complex than one could think, there is an open issue, but I suppose let’s keep that question for later in a specific Panache presentation that would be probably a good to exchange.
Georgios: Yeah, you probably have to break it Stephane here and get in to describe all the nitty gritty of Panache.
Max: So there’s a new question about the constructor…
Emmanuel: So I, yeahm is there any difference of injecting REST client in constructor instead of the instance variable?
Georgios: No, there is not.
I just wanted to show it because I wanted to show… Because in the CDI world or the Java EE world, whatever you wanna call it. A lot of people don’t use constructor injection. That was folks for the Spring world, think that, "Oh yeah, JavaEE doesn’t have constructor injection and all that weird stuff, but it’s been around forever. It’s just in all tutorials and stuff, you don’t see it being used that much. That’s just why I want to make the point here its just working out of the box, right…
Emmanuel: Yeah, that’s a good point, and it’s all done at compile time, so there’s no reflection really it’s all figured out at compile time. And we generate the right class to actually populate those either constructor or the setter and getter.
Georgios: Yeah, that’s a huge differentiator.
So getting back to the test, I should actually get to work up. The assertion, was failing it was saying that the name wasn’t great and that was my fault 'cause I didn’t have getters hopefully now, but I should get everything working.
Pretty sure I will. All right, yeah, everything’s working. So as a super easy thing to do, I just wrote a REST client here. And I verified that it works, but what we were hearing from everybody was like, "Oh yeah, you know what, that’s cool, but… And a lot of times I wanna mock this out. I don’t want to hit the real service. And that’s a very, very.
Max: Just two things: I saw, I think __ Or you couldn’t put regress client on this, right? Instead of putting it on a injection.
Georgios: Oh yeah, I should have, yeah, actually I usually… Yeah, I registered clients __ you’re right.
Max: But it’s equal to the same thing, right?
Georgios: I… Yeah, it’s the same thing, is the same thing as same thing. Actually, it’s a good point because I’m gonna have to update in order for the mocking to work that I’m gonna show it, I’m gonna have to update this, which is… And I would have to make it application scope. I’ll explain exactly when we do that.
Emmanuel: While you do that, I can explain a little bit, before we go into marketing. So here, so far, most of our tests have been kind of black box, so we say, "Hey we go and connect to that URL and we do something. And what not, but Quarkus tests actually is a being inside your app, so you can literally inject other beans so you can do what I would call more like your gray box kind of test where you can inject one of the bean to do some more surgery into deciding what you wanna test, and going on. So, I suppose by side effect will show that inside mocking but I wanted to present that because even as you don’t do mocking its actual a very, very useful feature set.
Georgios: Yeah, exactly, so in here, yeah, we in the test, if I did this _ on free in this country sure with object and the REST client, then that’s exactly as Emmanuel was describing if I did this, I could use this inside the test anyway I wanted because exactly, like I mentioned this is a B, so we’re gonna show something a little different. So we wanna mock this right, so we want in… When I do, when I hit _, I wanna have my own thing instead of hitting the REST service. So the whole idea here is that I added Quarkus JUnit 5 Mockito which integrates Mockito in JUnit 5 with our Quarkus CDI stuff.
So what you do here, when you call country service, and you would instead of inject you do inject mock, and because we need the qualifier, we’ll do REST Client. Like I said, same reason, we injected the… We use the qualifier in the injection point here, this is another injection point, so we’re gonna use the qualifier but now we wanna control it so this will give us a mock of country service, a mock that we can control with Mockito.
That’s the great part, ups, sorry… And then its, you just use Mockito the same way you’ve always been using it. Like I do not been using Mockito for a long time, and I always loved it and never, never thought to use any other mocking library.
So what I would do here, like I do Mockito when country service getByName please. And I would say, then the return collection _ and let’s say new country, and instead of Greece let’s say And _ So now what I’ve done here is basically country service will be the mock and it will replace the regular CDI bean, but only for this task. And that’s a very important part that this test will continue to use the regular external URL when we’re hitting this test here is the only one that’s gonna use the mock and that’s really what mocks are for, like per test, let’s say, alteration of your application.
So if I go here, I expect to get __ and I…
Max: That’s probably a good what you run it. Just be clear that inject mock is actually a Quarkus annotation, right?
Georgios: yes, yes exactly. I open imports here, it’s quarkus.test.junit5.mockito.inject.mock And now it’s failed, and I wanted it to fail because I need to explain why wait in this inject mock thing works. So inject mock works on normal scope CDI beans. Normal scope CDI beans are usually either application scope or request scope.
So, the Microprofile spec defines that when you create a REST client like this, and you don’t define a CDI scope that it’s dependent, it’s the dependent scope which practically means that in every injection point, you get a new instant self this country service, and that doesn’t allow us to create… it doesn’t allow us to create a mock because it’s already a JDK dynamic proxy and Mockito can’t already mock dynamic. So we have to do… We have to make this an application. So, by making this application scope this inject mock here will work and when I do and being clean test again, I should see all my tests passing now and they all pass.
Emmanuel: Somehow couldn’t we or __ detect that hey, it’s dependent scope. But then in some tests we wanna do a mock. So let’s actually have some sort of fake different scope.
Georgios: Yes, I got a… Basically, we discuss this with Steward and Martin and… Yeah, what we’re thinking is that we have some kind of bit code transformer that will be used and when you have this kind of inject mock thing, that will be used in it will alter the code of… Of the country service itself to actually take the mock into account. So that’s something that… That we’ll probably do sometimes soon…
Emmanuel: Okay, awesome. So we are 22 minutes before we end, so just a checkmark.
Georgios: Okay, good. One more thing about the mock. So let’s say I do since I’m using Mockito, Mockito by default, when you don’t define something, or turn a default response.
So if I do like country France and since I have it mocked, I haven’t told it what to do for France. What it will do is, it will return an empty list. So that’s just a Mockito thing I wanted everybody to be aware of.
Emmanuel: I just… I wanted to clarify, to Igor. This problem with the mock that cannot be the dependent type that cannot be mocked. So the workaround is to use application scope on your service, and that will be the workaround right now until we have a proper solution inside Quarkus, but that works actually that should have been application scope most likely anyways.
Georgios: Yes exactly, yeah the only reason it wasn’t is the spec defines that it should be dependent scope by default. Otherwise, I would have just made it application scope.
Max: So, we got another one. Georgio. Wanna take that, Emmanuel? How to mock REST client?
Emmanuel: How do I mock REST client test object to throw a 500 exception, http 500, but not using Mockito on his Quarkus annotation @mock and Eclipse Microprofile register client?
Georgios: I don’t think you can… Like with a mock, right?
I don’t think you can mock it to tail it, to return a 500. Well, what you can always do with Marketo is to tell it to throw an exception, but through annotations is… I don’t think you can do that. I don’t have anything, I can’t recall of anything but I would argue that if you were going to test something like that, you probably want to do what I wanna do now.
Oh, which is to actually use, to have the… Not mock the REST client, but to mock the external service.
So, what I planned to show now is that we continue to use the regular REST client, but instead of using the external rest countries service that I was using, I want to start a service like a proxy let’s say, that will intercept all the request to that service and in there, I can make it return 500, I can make it return 404, I can make it return any kind of error I want in order to test my actual integration. So in my view, that would be the proper way to test like http errors.
Emmanuel: That also answers __ sorry about butchering our first name, which is… Inject mock is grateful functionality test, but is there a way to verify that the correct annotations are used on the REST client and that would be exactly that. So you would have your server being a custom one and you redirect to that server and then you can run the properties, with the REST client in a fully control environment.
Georgios: Yeah, I think that’s the best way to test the end to end integration. That’s what I’m gonna do.
Okay, so let’s go like country service. If we do create a test to country service, this would be a Quarkus test and I’ll say __.
And I say, country service, inject client. Not the Junit assertions, I want the AssertJ assertions, are for that country service.
_ Unaudible typing! ! _. So this test, I haven’t been adding anything special to this test yet. I just wanted to set it up to show you that, what we’re gonna do here is that we’re gonna use the country service, but we’re gonna hit an external end point that will be controlled by us. Once I said once I get this going…
I passed the test… Now, we’re gonna introduce one more concept that is specific to Quarkus, then we’re gonna use WireMock in order to demonstrate.
So like Emmanuel said earlier, we run, we boot Quarkus once and then we run all the tests, against it. And what that means is that when you want to do something before you boot Quarkus you need as a developer, you need an integration point.
Well, the Quarkus test resource is that integration point that you’re looking for.
So wiremock contries… So I gotta create such an integration point or what I’m planning to do is now I’m planning to create a WireMock server where I mock, I set up basically the endpoints that I care about, and our test is actually gonna hit that server. How we do that? So we… We at this Quarkus test annotation test resource annotation we create a class that implements this Quarkus test resource lifecycle manager.
The stuff we care about, the methods with care. Are in here, or start which basically is the method that Quarkus calls back into the Quarkus test calls back into before it launches the Quarkus application, and what it returns is a set of properties that’s runtime properties that Quarkus, That will affect how Quarkus runs. This call is when Quarkus finishes, all the tests finish. So what we do here is a WireMock server.
WireMock server = new WireMockServer __;
And now, since we’re actually kinda running out of time, I just gonna copy&paste the actual mocking part.
I copied it from the stuff that I have already. And we’ll share with you being in the presentation so you can follow along. I’m gonna make this a Java 14, I’m on 14 now. I also have to…
Emmanuel: You wanna use the multi line, the the text which is.
Georgios: Exactly exactly, that’s exactly what I wanna use because as I hate writing JSON inside the little… , the regular Java stuff is just terrible.
So in order to do that, I need to enable some previews stuff.
So, Maven compile… This stuff isn’t actually important for the actual test, but it’s cool to see, show with Quarkus we have all the… all the flexibility to do anything you’re used to with Maven, or whatever to a…
Emmanuel: So it works with Java 14?
Georgios: Oh yeah, absolutely, absolutely.
It doesn’t work with records just yet, but we have a PR ready for that, so it should be working very soon.
Max: So you basically show what people can use in like four or five years in the production, so to…
Georgios: No, no, they can use it right now.
Emmanuel: Quarkus goes very well with the production, guys.
Georgios: Yeah, why not? So I have to enable preview both to compile and for surefire while running otherwise it will work, and I have to tell IntelliJ to use it causes not smart enough to figure out how I configure it.
So basically what I’m doing here is that I was subbing out the… the end point that this method is looking for and I’m saying when you see "gr" don’t return the regular green stuff, but return the same name, angry. So I’m actually just actually wrote Greek. And the other thing I did is that here, I told it to forward all the stuff that didn’t match here, I told it to forward to the actual, actual service and I need to do one more thing to get this working I need to tell Quarkus to use this actual, this server.
So, this serverm, once it started, it’ll start at some URL, some port… I don’t know which, but don’t really care because all I have to do in order to make the country service work, I need to tell it where the URL is, but wiremock base URL gives me that information. So what this does is that it overrides the property that I have here, which is the default. Let’s say this gets overridden by when I start here, because like I said, these properties that are returned by start or runtime properties that override, what’s in application properties.
Emmanuel: One of the question is, Is there a doc somewhere that goes into details at everybody’s own pace, that’s a lot of information that.
Georgios: Yes, I know, no, because I just came up with this when I was preparing for this.
Emmanuel: There you go YouTube like driven features.
Max: The feature is there it’s just the example is new.
Georgios: Yeah, I need to write down the example. Yeah, because this is a lot of information that it’s not…
Max: Once you’re done here, take this code and commit into a repo and push it, then we can go.
Georgios: I’ve already done that I’ll share once this is done, I’ll show you the URL.
Max: What’s the thing that… Like this start? What was the thing that made it whats the thing that made that being picked up? The lifecycle manager?
Georgios: Yes, the Quarkus test resource and it picks up these life cycle managers and I could have multiple lifecycle managers, I have one for database or whatever and they all run before Quarkus starts. That’s the important part. They run before Quarkus starts and they can override runtime properties.
Max: Very cool. So I was wondering about that.
Emmanuel: We have 10 minutes left, we haven’t showed the test containers, which is one of the questions we had. So let’s go do that.
Georgios: Yes, yes let’s do that really quick okay. So, I stay __ and going to test containers, I wanna copy paste the dependencies from here, I need to get to to do, let’s see, okay.
Emmanuel: __ this is getting awkward.
Test containers for information for people that don’t know is… Well, it’s a way to start from your, to control by your test life cycle, starting a set of resources inside a Docker container, on the same machine. And maybe on other machines like I don’t quite know, but the idea is you control the Docker start and stop of a database or JMS queue, or whatever you want to run your integration test. That’s very, very useful for that.
Georgios: Absolutely, absolutely. Yeah, we get that question a lot. So we really need to show this. So I just copy&pasted the Hibernate Panache ORM dependency, postgresql driver.
Oh, well, probably Panache, mock out for later. So you can talk about that when you have Stephane on the show. Since this is a feature coming in 1.5, it’s not in yet.
Okay, so let’s go create an entity "route". So that entity __.
Emmanuel: And here’s a good one. So, Antonio sais: what about debugging your test? I find it cumbersome to attache the debugger in IntelliJ, I think I see… Yeah, that’s for the test, okay, put it in on. It’s not… __ any applications running any testing running in IntelliJ to run the plain Java application from IntelliJ and attach the debugger… Now that we have the command mode that’s much easier. I don’t know about test like what would you…
Georgios: This will work if I do this, let me hit, okay, I’m at Country service, if I go to country resource like yeah.
Max: If you’re in a test just click that debug in anything.
Georgios: __ you don’t work well now I’ve had it a bunch, of dependencies, but yeah, I got this thing. A regular testing out delete anyway, so let’s say I did this now I have all the Hibernate stuff inside, let me take-out Hibernate, so I then… So the.
Max: Are you trying, just to add the test containers on top or what are your…
Georgios: Yeah, I was, I was starting the test containers thing. Yeah, exactly, but now I wanna show the actual debug…
See, debugging works just like any other Java application JUnit test, it’ll work because the idea, it works because it’s in the same JVM, I mean the test runs inside the same, the application and the test run inside the same JVM.
So debugging, just works.
What is a little cumbersome at the moment is dev mode inside the IDE. So with dev mode the easiest way to do it is you do mvn quarkus: dev and then you attach a remote debugger later on.
And most people are used to that work flow because they’re used to running their java-jar from the IDE or wherever, all the time. But with Quarkus dev mode, it’s a little different.
You just start it on the command line, you forget about it and you attach a remote debugger.
And that’s how I…
Max: So I just… You to add to that, VS code actually does it when you do, it sets up a default launch, the you press F5, it will start quarkus dev and connect a debugger for you, so you don’t… And I didn’t actually realize this until Fred told me that its so lightweight and I think we’ve got… I wanna see that we have the same thing to IntelliJ and Eclipse… 'cause it’s just, it’s nice 'cause I…
Georgios: Yeah, it’s awesome 'cause people expect it to work, they don’t understand that it’s not obvious, like when you start Quarkus dev mode then a different process starts and that’s the process you have to connect the debugger to. Yeah, it’s not exactly obvious. So yeah, having… That would be great IntelliJ as well.
Emmanuel: Alright, let’s go back to test containers.
Georgios: Yes, yes, yes, I… Let’s finish that up. So, fruit resource I can, I created a fruit entity. With Panache I obviously don’t have to write almost any code, so everything will just work out of the box. So, I go public List fruit.
Emmanuel: By the way, we should have even less code at some points in the near future, so just as a teaser… From a resource talking to Panache entity.
Georgios: Yeah, you know what’s coming.
Emmanuel: I don’t know when, that’s the problem… I live in the future.
Georgios: The PR I think, is pretty much raised. Stephane is reviewing it but we should be close. Ahhh fruit listAll… Okay, so this will just list all… And I now I need to do create fruit resource test… And this would be a Quarkus test and now when I add a different test resource, a Quarkus test resource. So I need to start the database before Quarkus starts, right?
So if I go here, and d test containers, database.class, create a class then again will be a Quarkus resource manager, and since we don’t have much time I’m gonna copy&paste it.
So what it does here basically is I’ll write this real quick and then explain what does… So the idea is, the resource with a test resource lifecycle manager will start a it’ll start a test containers postgress skill database.
So here I’ve told it version 11.7 with database name, username, password, thats just some simple defaults and the important part here that start, I start the database, and then I define the Quarkus runtime properties, so that would be the data source runtime properties. That be the user name, the password in the URL and just like WireMock did same way post the test containers gives me a JDBC URL that I can just use.
So this way I just, I don’t have to configure anything with darker and pom.xml or have a Docker container, running anywhere other way I just integrated with Quarkus test containers and it’ll just work. I need to fix a few more things to make this work out of the box, the, this is the test specific that I’m telling it, it’s a database, Postgress databas, drop and create the database for the test. I’m gonna seed the database but some data and you just… So, fruit and I need to copy like let’s say this that because the…
Max: That is just using test containers? And I guess the only thing I had to do is used a wiring up with the Quarkus test resource.
Georgios: Yes, exactly, Yeah, to start test containers before Quarkus starts.
So this should be always plain. I seeded the database with three fruits and that’s why in my test I said that I’m expecting three… I’m definitely… Okay…
Max: Java 14…
Georgios: So sdk man, I totally endorse it as the way to use Java 14. and now just running again and let’s see. So, test containers starting here, we saw it did we started, test passed and it was not easy, right? So you saw it… All I need is a test resource start the database on the important thing is to set the property, the runtime properties, I need and it just works.
Emmanuel: So just quickly taking the __ sdkman.io and it’s a way to select the Java you want and a few other things.
You got a bunch of options here, but if you jumped from one JDK to another, the GraalVM one or just hte non-GraalVM one. A very useful tool.
You also show the test containers. And I wanted to show that it’s not limited to databases you’ve got quite a bunch of other things like Kafka, elastic search, __ etcetera, etcetera. So that’s quite good. And integrate with JUnit 5, which is the one thing we’re using right now, so that’s… There is one tiny things, they don’t do which is really sad, is they do require the Docker demon, which means we can not use that with podman, which is a bit of a shame 'cause that would be super useful… But otherwise it… It’s working great yep.
Georgios: Yeah, hopefully that will restriction will be lifted… We may be lifting soon, who knows., well, we have…
Max: We hit the hour. Is there anything else you wanna do?
Georgios: Well, yeah, basically the URL for all the code I showed you can find it. I know how it is posed to share. Do I just post it in the chat?
Max: Yeah, I just toss it in chat, and then we will put in the blog when it’s coming out, yeah.
Georgios: Oh, okay, great, great, you on.
Emmanuel: Okay, and tell us how you felt. Was it too technical, not technical, enough, too fast, too small to be perfect, to perfect or… And then on the chat live, when it’s still alive, otherwise go to the video, post comments in there and don’t forget to subscribe to the Quarkus challenge or YouTube.com/quarkusio. I realize you don’t need the "c" here, So let me remove it, click here, there you go… YouTube.com/quarkusio - hit subscribe and I’m not sure if it’s gonna be a weekly event, or bi-weekly event bi-weekly meaning every two weeks for the confusing English. People like me.
Max: No questions?
Emmanuel: Yeah, there’s one question, so let me go back to… "So why did you prefer Maven over Gradle?
Georgios: For the simple reason that I’m more familiar with it, right?
Quarkus works with both let’s say some of the edge cases like the very edge cases, work better with Maven, the Gradle support is being looked into it’s going to get way better over time. But the reason I used it is because I’m more familiar with Maven.
Max: The essence of the Maven/Gradle discussion is, So there’s some issues we can’t fully handle in Gradle yet but we are hoping to fix it, but I also wanna say as far as we know, right now, about 70% of the people who goes to code.quarkus.io of chose Maven and the other chose Gradle.
So yeah, it’s a bit… They’ll be improved, yeah.
Emmanuel: And Georgios was too fast, so we need slower coders.
Indeed there is a little bit of a lag with YouTube Live, hopefully it won’t be too visible in the actual final video once it’s all fully uploaded and properly run, but although it… Good feedback on that.
Max: Alright, we’re good.
Emmanuel: Yeah, we’re good, thank you everyone and see you, well, sometime in the future sees __ what we’re gonna try and do, but who knows? And happy May the Fourth to everyone.
Georgios: Thank you everybody!