Software Testing Tutorial - Learn Unit Testing and Integration Testing

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what's going on guys assalamualaikum welcome to amigos code in this crash course you're going to learn how to properly test your applications i used to have this thinking writing code to test my code but i have to be honest with you if you want to become a real software engineer then there is no way there is no way that you should be deploying code to your users without writing tests so in this course you're going to learn about unit testing integration testing mocking and a bunch more without further ado let's kick off this crash course before we kick off this crash course this video is sponsored by diff blue diff blue offers a powered ai unit testing coding generation tool for java developers diff blue writes both your unit and integration tests with a click of a button allowing you to focus on your business logic whilst increasing your code coverage as well as speed up your development and making sure that you don't break anything diff blue free community edition is available as intellij plugin which is the ide that i'm going to be using for this crash course and for those watching this video you can get a license upgrade allow you to write unit and integration tests for java commercial or open source projects link will be in the description of this video this all for now let's begin in this session let's go ahead and focus on testing so right here i've got the uml diagram for the application so far and what i want to do here is to break it down for you super simple so you understand exactly how to test your applications so in here remember we have the student repository and this is an interface and we have one method right here called select exists by email and then it takes an email of type string and the return is true or false and the plus sign in here means that this is a public method now remember this interface right here is responsible to talk to our database right here and then we have the student service and this service right here has a private field so you can see that the minus sign so this means a private field of type student repository so this service uses this interface right here and then it has three public methods get all students which takes a student and then returns a list of student then we have add student which take a student and the return type is void and finally we have the lead student which takes the id of type long and then returns nothing right so this is void right here so both student service and student repository these are the units and i'll tell you why in a second so these are the units that we want to test and then in here we have the repository so this repository remember it's responsible for taking all the requests from the client so this is our api in here and this is why i named this as integration and you'll see why in a second as well but basically what we need to do is let's start from this side right here where i'm going to show you how to test the repository and then we're going to move into the student service and then i'm going to show you how to properly test the repository as well so the student repository so testing is something that you should really master and you shouldn't know how to test your applications properly if you are serious about programming and writing good quality software then testing should be one of the things that you have no second thoughts it should be something that you have pleasure doing and you'll see that testing is not that difficult so previously i've worked in companies where they didn't do any testing and to be honest the code quality was really bad and deploying the application to production or to any environment was really frightening because having no tests gives you no assurance of the quality of your software so if you introduce a new feature then you don't know whether you have broken anything so that's the power of testing so i want to make sure that you fully understand how to test your applications and next let me go ahead and show you exactly what we need in order to start writing tests in order to write tests in the java world you will most likely be using junit 5. junit 5 is the fifth major version of the testing framework for java and the jvm so they say that junit 5 is the next generation of the unit and this is because from version 4 to version 5 there was a massive refactor and improvement now in here i'm going to click on user guide and you can find the link under the description of this video so let me click on it and right here they give you an overview of j unit what is unit 5 so it's equal to the platform jupiter and vintage and right here the platform serves as the foundation for launching testing frameworks on the jvm then we have the jupiter so combination of the new programming model and extension an extension for writing tests so these are like the annotations that you'll see in a second and then we have the vintage which is basically a test engine for running junit 3 and 4 base tests so these are the older versions of junit so right here if i scroll down you can see that we have this section so writing tests and have a look so this is how you write test so you have a class and then you have your under test so in this case calculator and then you have a method in here so void you give it a name and then inside you'll be performing one or more assertions so here you can see that assert equals and then this is the expected value and then the actual is when you invoke the end the test class in this case calculator dot add and then one plus one and this should equal true therefore this test will pause so in here you have a bunch of annotations and in here you have a bunch of annotations that you can use so at test denotes that a method is a test method and then you have parameterized tests repeated tests factory template display name before each after before all nested tags so on and so forth and you can even disable a test as well including timeouts so right here you can go and basically just read about all of this documentation and one thing that i want to show you here before we move on is that you see that we say assert equals so in here this is how you perform the assertions if i click on this tab right here so this is where i have the assertions and this is the class assertions for junit 5 and basically you can see all of these methods so a sear all where you can pass a string and then you can basically say a cert array equals and if i scroll down you can see that a bunch of methods so assert not equals and then assert same as their throws for exceptions timeout so on and so forth so and also assert true for booleans so in here what i'm going to show you is there is a better assertion library that the one junit five provides and that is a certain j so a third j provides a rich set of assertions that improves your test code readability and is designed to be super easy to use within your favorite ide so here you can see that for example this is how you use it so if i zoom in a little bit so you can see that you import a set for j and then you can say insert that and then dot is equal to and then you have methods such as assert that and then starts with ends with and basically you can chain all of these right so the same void arrays or lists you can say has size something and then contains does not contain um and also asserting for example exceptions this is how you do it so on and so forth so i actually prefer a cert j instead of the assertions provided by junit 5 and this is what we're going to be using in this course so now that you know about junit 5 and assertions next let me go ahead and show you how to get your first test up and running if you want to follow along and basically try for yourself go ahead and basically clone this repo and check out the branch number 12 right here so after github actions so you can basically clone this and then check out this branch right here or you can just basically just download the zip but it's best if you use get so i'm going to leave the link under the description of this video so you can just check this branch now let me go to intellij and in here remember i said that we have the student controller repository service and also we have couple exception classes right here so let me first show you that in order for us to get junit 5 we don't have to do anything so here go ahead and open up the palm.xml and if i collapse this for a second and in here you see that we have this dependency so all dot spring framework dot boot and then spring boot starter test and then the scope is test which means that we're just using this dependency for testing purposes now if i click on this artifact right here so i'm just going to press command and then basically click on it and you can see the keyboard shortcut command b or control b for windows now in here so basically we have a bunch of things but if i quickly show you so if i scroll down you can see we have dependencies and here we have some auto configuration json path xml bind and have a look sir j so remember i told you about assert j so this is already included for us which is really nice we also have hamcrest so this is another assertion library and then we have junit in here have a look junit jupiter and the version is 5.71 so this is the default that comes with the spring data test and we also have mokito so we're going to use mokito later so you see how we do mock classes but this is pretty much everything that we need in order for us to start writing tests so which means that we don't have to go off and install anything which is really nice let me close this and next let's go ahead and write our very first test in order for you to write tests for your application in here if i expand the project tab and you see that the maven folder structure is so src and then we have main so this is where the main code lives right so all of this you've seen and then if i put this back you can see that so we have main and then we have test so in here test so if i click on test and right here you can see that we have one default test so if i click on it and have a look so we have this class called demo application tests and then we have one single test so this test doesn't do anything in here we have this annotation at spring boot test and i'm going to show you this in a second but for now let's just delete this and what we're going to do is let's just basically you can see that we have this play button in here or here so basically this will run all tests found within this class or you can run a single test so let's just run all tests and you see run demo application tests and there we go you can see that the process has finished and here you can see that we have some test results so this basically took 45 milliseconds this was the class and within that class we had one test called context loads and it passed so this test is pointless so let's actually go and collapse this and let's change this to it and then shoot and then add and then numbers so here let me just create a class within this demo class so here i'm going to say class and then i want to say calculator and then inside i'm going to have so i'm going to say int and then i'm going to say add this will take two integers so into a and then int and then b and it's going to return a and then plus b so this is the example that you saw before and here if i basically end this with semicolon there and then format things and we have our calculator now let's create an instance of this class right here so here we're going to say calculator and i like to name these are under and then test because it's the class and the test equals to new and then calculator now in here what i like to do with my tests is to have comments to lay out the foundation so here i'm going to say forward slash forward slash and then given and then i'm going to say int and then number 1 equals to 10 for example or 20 and then int number and then 2 equals 2 and then let's say 30 and here i'm going to say when and then when we say under test dot add pass the number one and number two so this will give us an integer so if i extract this to a variable and i'm going to name this as result and then finally i'm going to have then and then here i can perform the assertion so here i'm going to say assert and then that and here i'm going to basically import so here import static method and then check this out so we have a couple of imports so you can see that we have org.srj core.api we also have hamcrest and we also have this one which is deprecated so let's select the first one and then i'm going to say so here basically it takes d you can see the actual so assert that and then result dot and then is and then equal to if i press or basically i don't have to press command p you can see now we have the expected value so what i can do is say right so the expected value for me is actually 50 right because 20 plus 30 is 50 right so here i can just end semicolon and we can also take this to a variable and we can say expected so it's really up to you whether you want to name things and now this is our very simple test so let's just quickly run it and check this out so you can see that the test passed so here we have it should add numbers and maybe we should say it should have add two numbers right so let's just change it quickly it should add and then two numbers let's run it again and there we go so this test passed right and this time it took a little bit longer so 99 milliseconds because we had some extra steps in it basically this is a basic unit test using junit and a search j so let me just recap once more so this annotation right here at test this is j unit right so this tells that this method is a test method and then we have basically in here i'm actually using bdd's test style so given when and then then so this makes it super easy for someone looking at the test and understand exactly what's going on so given so these are the inputs and then when and the test with the method that you are trying to test is invoked in our case add when we pass the inputs number one and number two we then say then and then the expected so we expect 50 and then we perform the assertion so assert that the result is equal to expected now if i was to change this to 51 for example let's just run it again there we go you can see that this failed and it says expected was 51 but the actual was 50 right so here expecting 50 to be equal to and then 51. so there you have it let me just clamp this and you can see that this went red and let me put this back to 50 and there you go so this is your very first junit test with one assertion next let's go ahead and test this student repository interface right here which is a little bit more interesting right let's go ahead and test this method right here select buy and then email so let's go back to intellij and in here i'm going to open up the project tab and then i'm going to navigate to java so main java and then inside of student we have the student repository and this repository you can see it's an interface and is this interface that we want to test so again this talks to this database right here so in our example so you saw that we have so if i just zoom out a little bit and then just zoom in here you saw that we have a postgres database running right so for testing purposes we're not going to use the postgres instance that we have locally and i'm going to show you a better way that we can do this so let's just quickly go back to intellij and if i put this back just like that it's kind of hard to zoom with the trackpad there we go so i think this is uh good for you there we go so in here the way that we're going to create test for this is you saw that if i open a project you saw that we can basically um in here we can say right so we can write or actually we can right click and then we can create new package we can say student and then inside of student then we can say student and then have a new interface and this will be oh actually a new class and and then this will be student and then the repository and then test just like that enter and then we can go and basically write a test right so you saw that this was a bit manual so let me actually delete this package inside of the test folder and i'm going to show you a better way of doing this so in here inside of this interface go ahead and press shift command and then t or shift control and then t if you are on windows and right here you can see that we have choose new test for repository so zero found and that means if you have a test you will just navigate into the test class but here what we want to do is create a new test so create test and then you can see that this is pre-populated so testing library junit class name so basically this is the same class that we had just a minute ago and then for the subclass we're just going to leave it as is and then destination package you can see that this follows the same package as the one you have in main right and then we can set up the uh basically we we can have the setup method and tear down so on and so forth and right here you can see that generate test four methods and then member so select and then exists email so let's just tick this and okay and there we go so you can see that we have a test class so this was some auto generating for us and you can see that basically we have the exact same thing here expand you can see that we have show repository and then test so now we can write our test so here let me just say it and then should and then select and then exists by email and i think we should have a better name here so it should select it should check if and then student and then exists by email and basically the name here doesn't really matter you can go as long as you want but as long as it makes sense that's what matters so in here now what we're going to do is so let me just remove this import because we're not using assertions from to unit and here let's just say that we want to basically we want to auto wire so private and then say student and then repository and here i'm going to say under test and then end this with semicolon and in here i'm going to auto wire so here i'm going to say at and then auto wired and you'll see this in a second and now what we can do is basically set up the given when and then then so here let's go ahead and say that given and then when and then then and i'm missing an n in there so given a student so let's say student and then equals to new and then student and then inside i want to have so basically uh let's just have name so i'm going to say jamila and then email will be jamila gmail.com and then gender and let me put this on a new line there we go just like that and by the way do not type name and then column and then email look and then call them so this is intellij given me hints so here if i say um do not show and then hints for current method you can see that that goes away right so here if i press semicolon there so we have a student and what i want to do is so given so here i want to say under test dot and then save the student and then i want to say when and then under test dot and then selects exists email in here let's just pass an email so here i'm going to say let's just extract this to a variable as well so email and then here i'm going to say email and then this returns a boolean right so exists there we go and this can be lowercase boolean and then so in here then i want to say assert and then that and if i press option and then enter or you can click on this bulb right here and then import static method and make sure it is the one from sir j core api and then i'm going to say exists and then dot is and then true just like that and you can name this to expected for example so if you want so expected there we go and this is our test so you can see that it's really straightforward right so as you have the given when and then then it's very easy for you to set up your tests so given a student right so here we're doing all the prep work so we have an email the student we save the student so all of this is part of the given and then when we invoke the under test and this is the method that we are testing then the assertion is so we say assert that expected is true right because we know that this method should return true because this email is already owned by jamila so before we actually run this test there is something that we should configure because we don't want this test to run against our database right here so remember i said so in here we have so where is it so in here right so we don't want the unit test to run against our postgres instance but instead we want this to run against an h2 database which is an in-memory database next let's go ahead and configure this in-memory database right so as i said we want to run our unit tests for this student repository against an in-memory database we don't want to run the tests against our local database because the data produced by these unit tests we don't want to keep them in our database and luckily for us we have this database called h2 and h2 is an open source sql database and you can use it as an in-memory database so to set up this in our application to use it for testing it's really straightforward so if i open up intellij and in here open up project and then go to palm.xml and what we're going to do is the following so in here it doesn't really matter where we add this but let's just see right after the spring boot starter test let's add a new dependency so dependency this will be h2 and then the group id will be com dot and then h2 dot database now if this is right for you what i want you to do is just go to project and then open up palm.xml right click and then actually before we do that let's also set the scope for this as they have then in here so the scope for this right here is test let's also do the same here so scope and then test now open up the palm.xml right click and then go to maven and then reload project and that should sort this dependency out so now that we have this dependency what we need to do is to remember in here we have application.properties so application.properties and this in here connects to our local database right so our postgres instance so what we're going to do is the following we're going to so we're going to create a new folder under so java so test and then java and we want the exact same thing right in here so main java resources test java and we also want resources so i'm going to right click and then in here if i say new and then directory i can pick this maven source directories so pick that and there you go now take this application.properties in here command c and then put it inside and then okay now this application.properties is used for testing and what we can do now is basically in here we can remove all of this so let's remove that basically we can actually keep all of these but one thing that i want to change is so in here the data source url as well as the username and password so the url instead of postgres this will be h2 and then here we want an in-memory database so say mem and then column db and then and then semicolon and then db and then underscore and then close underscore delay equals two and then minus one so this is some configuration that we can add for our in memory database and this should be close just like that then for the username we want this to be sa and then password as well as a and also what i want to set is the driver and then class name and this will be org dot and then h2 dot and then driver just like that and this is pretty much everything that we want and in here instead of say update let's say create drop so basically we want to have a fresh database every time we run the tests now let's go back to our student repository test and let's actually just try and run to see if things will work but i can tell you that it's not going to work and this is because we need a special annotation so here let's just try and run the test class and there we go so you can see that we have a no pointer exception and it says that and the test is no so this is correct and that is because we are missing an annotation that will basically wire up everything so basically it will start the application it will connect it will it will get a data source from the configuration that we have and then we're going to auto wire things so there we go now that we have h2 configured next let's go ahead and get this test class running and then also add a second test right you saw that this test when we tried to run it it did fail and that's because in here this test so we have a test for this interface needs to connect to the h2 database now anytime that you are unit testing your repositories you need to use this annotation right here so i'm going to say add and then data jpa test and this is the magic that will glue up everything including auto wire the student repository and you can see that the error went away and also spin up the database for us so let's actually just for a second let me just put a breakpoint in here and i'm going to debug this so we can debug or i can just right click on the method and then debug and now check this out this is familiar right so you can see that if i go to log again so i just want to see that it actually connected to the database and in here this is actually paused but if i inspect the under test right here you can see that this is a jdk dynamic proxy and we can use it so let me just stop this for a second and then here let me collapse this now remember before this failed so let's run the test again so i'm going to click on the class and then run student repository test and you can see that we have the familiar logging and check this out so let's have a look at the logs so you can see that we have some logging create table if exists so this is because of this logging right here this one show sql and to be honest if you want you can get rid of those because it's just noise on the console but for testing is absolutely fine and you can see that we have create table and then we have some shenanigans about the insert and then this is our select exists method so this is when it was invoked and this is when the test ended so it dropped if exists and you can see that our test did pass so which is really cool right so let's now focus on testing so now that we have things up and running and working you can see that this test did pause now let's have a second test let's just duplicate all of this in here command c and then i'm gonna paste that and in here it should check if student and this name should actually be if student email and then exists so that was a mistake there and here it should check if student email and then does not and then exists you can basically improve on the name of these methods and this method right here what it should do is so let's just remove this save right so we're going to remove that save because we don't want to save anyone into the database and here the expected is given this email and then when select exists email this should be false so is false because there is no one with that email there we go so you can see that how easy it was for us to write a second test so let's just run this one test and you can see that this test did pause now one thing that i want to do here is i want to have so i'm going to press ctrl and then enter and here i'm going to say setup and then here i want to say teardown and then after each test i want to say under test dot and then delete all so i want to delete everyone so after each test i want to delete everyone which means that for each test we'll have a clean state now let's run all the tests in this class and you can find all of this code and the description of this video and there we go you can see that we have two tests and they did pass so they are doing what it's supposed to do so this is really cool now one thing that i want to mention is that the only reason why we are testing this student repository is because we have this method and this is our own custom method so we wrote this sql query and it's important for us to test that our queries indeed work but you see that so if i go back in here if i basically put my mouse anywhere so here i can say under test dot and then this has a bunch of other methods right so delete all exists find by id save so on and so forth right all of these other methods we don't have to test them because we didn't write any of that and it's provided by spring data jpa and it's already been tested that's why they provide it to us as an api that we can use so for those methods there is no need for us to test them because it's given to us for free the only methods that we have to test are the ones that we add in our interface in our case we tested that when we call this method right here we tested both scenarios where the email exists and when the email does not exist so it should check if student email does not exist and then it should check if student oh actually let's just say when so naming things can be really difficult sometimes but if or when it's it's the same thing so there you have it hopefully you know how to test your jpa repositories so it's really simple and if you break down things with given when and then it's a piece of cake testing your repositories next let's go ahead and learn how to test the student service and if you have any questions please do let me know right so we have tested this student repository now let's focus on student service first i want to show you how you might want to test this which will be the wrong way of doing things and then i'm going to show you how to use mocking so in here let's go ahead and open up intellij and let's open the student service class and what i'm going to do is i'm going to press shift command t so i'm going to create test and you can see that we have the dialog create test and there we go so junit 5 and then we have the class name and we can have the setup so here set up before tear down and then get all students add student so and so forth let's just click on these three members and by the way we're going to learn about setup and teardown in a second so we're going to use them and just say okay so now in here so we have the student service test right here and we have three methods right so currently i can just even say add and then disable so this is you learning a new annotation and this will disable these tests which means that they won't run so i disabled and they won't run now in here i can go ahead and let's test that we can get all students so you might even think that the best way for you to test this and by the way let me just remove the jupiter api assertions because we are using a certain j so in here you might think right so in order for me to test geostudents we first need to have the and the test so here let's say private and then i'm going to say student and then service under and then test and here let me just press ctrl and then enter and you can see the keyboard shortcut and i'm going to generate the setup so in here we could actually have selected this method from the previous dialog but in this setup so this will run before each test i'm going to say under test equals to new and then student service now inside we need to pass the student repository now the way that we're going to do this is the following so in here i want to say private and then student and then repository student repository and then pass a student repository in here just like that and now before each test we're going to get a fresh instance for student service now in here let's just say that let's change this name here to can and then get all students and what we're going to do is the following so basically this test is super simple and that's because if i press shift command t and go back to student service you can see that the only thing that it does it just calls student repository dot find all now when it comes to unit testing if i go back in here for a second remember this string repository has been tested we test it in isolation and we know that it definitely works and inside of student service we have a reference or we have a field of type student repository now you might be thinking that perhaps we can go back to the test and then here so this should a repository maybe we can just say add and then auto wire right and then we get the real instance for student repository and then we can add new students delete so on and so forth but in reality we don't want to do this right we don't want to do this because this student repository we know that for fact indeed its implementation is good enough right so every single method that we have in it does work and this is when we mock this student repository so we say right so here we want this to be a mock using mokito so this is or mokito just like that and now what we need to do is the following so here in order to initialize this mark we need to say that mokito annotations dot and then open marks and then inside let's just say this so basically if we have more than one mock it will initialize all the marks in this test class and this so this returns a closable you can see here closable and what we're going to do is the following we're going to take this just like that so i've just pressed shift command v to extract to a variable and here i'm going to say this will be private and then paste that and here i'm going to say that this will be equal to that and then after each test so um after oh actually t down method so here after each we're going to say autoclosable dot and then close so this allows us to close and this actually throws an exception so it's fine let's just say that we change this method to throw this exception so this will allow us to close the resource after the test and now so we have things set up so let's just in here so now we can go back to testing our method and the way we're going to test this is we're going to pretty much just say when and then under test dot get all students then in here we're going to say verify and we need to import this from akito so here import static method and this should come from okedo so verify and this will be our mock so student repository and then i can say dot and then find all so we want to verify that this repository was invoked using the method find all so you can see that this is a little bit strange right but what is happening is we basically don't want to test the real student repository when we are testing the student service because student repository we know that it works fact and then we can just mock its implementation inside of the student service test and the benefit that we get with that is that our unit test is now fast so we don't have to bring up the database create the table so on and so forth insert a new student drop the database and all of that stuff that you've seen when we tested this repository so we've done that work once therefore anywhere that we use this repository we just mark it as we've done it within this student service so in here this is what we're doing so basically we have a mark so let me just put like that so we have a mark for the student repository and then auto closable and this is because of mokiro and i'm going to show you a better way of doing this in a second and then we have the after each which we then close the resource and this is our test so if i run this test you can see that it works right so here if i say verify that the method delete all was invoked so this should fail there we go so this fails right and it failed because you can see that wanted but invoked delete all right and you can see that however there was exactly one interaction with this mock and it was find all so if i go back to the student service so shift command t in here so when the end the test was invoked so get our students the mark was invoked with find all and again we just have to verify that this is called because we know that whatever this returns indeed does work and also we didn't write this method find all and this is a good way of us actually marking things right because this is given to us for free and we just rely on its implementation so there you have it this is pretty much how you test using mokiro now one thing that i want to improve here is you see that this can be like um a little bit confusing and some boilerplate code so let's just remove this let's remove this as well and let's remove this this this and that line and then in here so for this class we're going to say at and then extended with org.junit.jupiter api extension and then here i'm going to say mokito and then extensions dot and then class so that will actually do what we had before so you can see that this is much cleaner now now if i basically run all the tests in this class you can see that the test failed and that's because we have to change this verify in here to find all and let's run the tests again and uh you can see that it works and these two tests are disabled that's why they're like that and you can see ignored two out of three tests so there you have it if you have any questions drop me a message otherwise let's move on and test the add student method right so let's test the add student method so here let me just show you again so if i go to student service so add students so this is what we want to test right so add student now here we're going to use mocking again because remember we tested that select exists email works right so we have tested this method so in here remember before in the repository so we have two tests so one that checks when the email exists and the other one that checks when the email does not exist so when it comes to test this this is what we're going to do so here i'm going to remove this annotation at disabled and then i'm going gonna say can and then add and then student and here let's basically uh we need to grab one student so let's just copy some code so from here we have this student there we go and if i go back so can add student i'm going to paste that and then here i'm going to indent or actually inline that so now i'm going to say given so i like to have all my givens so given and then here i'm going to say when and here we're going to say under test dot and then add student we're going to pass the student and then here we want to say then right so what we want to do so what we want to do is we want to basically check that so student service let's go back we want to check that the repository so student repository was invoked with the same student that we passed so how do we test this using mocks well it's very simple so here what we need is an argument capture so i'm going to say argument and then capture and this will be student just like that i'm going to call it student argument capture equals to and then argument capture so oops so argument capture for class and then student put this on a new line just like that so now what we want to say is so here we're going to say verify and then we want to have our mock so student repository dot and then save and then here i want to say student argument dot capture dot and then capture and this might seem a little bit confusing but the reason why we're saying right so we want to verify that the repository was called with save but in here what we what we are doing we are saying we want to capture the actual student that was passed inside of this save method so in the student service so here so when we say repository.save we want to capture this value right here so here let me just go back and now the assertion that we have to do is the following so now that we have the captured value here using argument capture we can say argument capture or student argument capture dot and then get and then value this will be a student and now i want to extract this way variable so this will be the um captured and then student and what we want to do is say assert that and then i'm going to press option and then enter or you can click on this bulb right here and then here actually we just need these parentheses so that this works and assert that so import and then static method and then assertions for class types so let's just pick that one and here i can say captured student dot and you can see that before we used to use is equal comparing field by field but now it's been deprecated and we can just say is equal to and then student so this student right here is the one that the under test receives and then the captured student is what this service here receives so the studentrepository.save we capture this value and then basically we're just comparing that this student what we pass in is the same one that the student repository dot save has been given as well now if i go back to the test and here let's run the test so here just run this test and there we go so you can see that this test did pause which is really really awesome right so hopefully this wasn't too confusing but this is something that you have to get your head around and make sure that you understand exactly what's going on but in a nutshell we have the given and then when the under test dot student is given this student right here we verify in here so we verify that the repository and we actually capture the values so we verify that the repository was invoked with the save method but at the same time we captured the value so that we can actually make sure that the value is the exact same one which was invoked by the under test if you have any questions go ahead and let me know next let's go ahead and have yet another test for the opposite so when the email is taken before we write our second test what i want to do with you here is go to the top of this class and right click on this play button right here or actually just click on it and then you see that we have run student service test with coverage we can also achieve the same by right clicking go to more debug and then run with coverage so let me just run with coverage and there we go so you can see that we actually have this pop-up right here and this is the coverage and what i want to do is the following so you can basically click on it and you can see that in here so let's just zoom in a little bit i'll actually expand this a little bit you can see that we have so this is the coverage right so the class student service right here so the class has 75 percent right here coverage the line coverage is 53 and then the rest you can see um we have some numbers here but we didn't actually do much around this area so let me just hide this and then go to student service and what i'm going to see now is have a look we have these lines so green and red so green means that this actually has been covered by our test but red means that we are missing some tests yes we are missing some tests so we're not testing this scenario right here right and this is what this coverage is telling us so intellij is quite powerful and quite nice when it comes to testing and you know giving us information about what we need to test so let's go back to the student service test in here and what we're going to do is test that when the email is taken our code will throw an exception so in here let's just basically grab all of this and usually with testing there's lots of copy and pasting so paste that and then we're going to change the name for so will and then throw when email is and then taken so here's what we're going to do so this will be the folly so given the student and then when so when this is called we want to make sure that we have an exception being thrown so this will be combined so when and then and at this point we can actually get rid of all of this so just like that and that as well so now with a certain j we have a cert and then thrown and then buy and here should be assert and then that and then thrown by so import static and this will come from assertions and in here so this works as follows so this takes a lambda just like that and then here we can say thought and then has and then message and we can say has message containing and basically so if i go back to the actual test so this is the message so email and then this is uh taken so let's just paste that and then here i'm going to say that and this will be student.email so this is basically jamila right so this email right here and also we can say so before that we can say dot is and then instance of and if i go back again to the basically student service but request exception so let's just take that paste that dot and then class and there we go so basically this is what we want to test right but now if i run this i want to show you that so let's just run this this will not work and you'll see why in a second so there we go so expecting code to raise a throwable but what is happening is so let me actually just run this in debug mode so debug and let me go and put a breakpoint just here right so let's debug again and this will make sure you understand exactly what's happening there we go and have a look so boolean and then exists email so this exists email is false right this is false and we want it to be true but currently we're not telling our mark that when this method is called with this email or any given email to return true so by default if you don't specify a return value it will just default to false which is our case so let's just stop this and then go back to the test and in here what i want to do is say given and here let me just import the static method and this will come from mokito so bdd mokito.given and here i'm going to say studentrepository dot and then our method so select exists there we go and then we can pause the email so here i'm going to say student dot get email and after this i want to say dot will return and then the boolean value which is true so let's run this again in debug mode and now check this out we said true and which means that this will fall inside of this if statement so now we are controlling exactly what happens when this select exists email is invoked so let me just close this or actually stop this and then here let me go back to the test and we can run the test and there we go you can see that the test did pass now here i could also say let's say that i do have for example um basically i said emay right so if i run the test again this will fail and there we go so you can see that expecting throwable message email jamila taken and then basically this was what we are expecting right which is incorrect so i just want to show you that this is actually working so email and then space there and we are good to go so one thing here also is what you can do is if you don't if you don't want to pass for example the email here you can say any and then string so if i run this again you can see that this works and there you have it finally one little improvement that we can do with this test is that right here you see that we are asserting that thrown by which means that if i go back to the service in here this method is never called right because we throw this exception right here so let's go ahead and actually reflect that in our test so here after this line right here i can say verify and then i'm going to pass the mock so student and then repository and then i'm going to press comma in there and then the verification mode so this will be never dot and then save and we can say any so just like that right so we are saying that this repository right here so our mock it never saves any student so again if i go back to the service in here you can see that this method right here it's never executed and this is what i'm actually saying in here so if i run the test again and you can see that this also works now if i collapse this and then scroll up so the final thing that i want to do is let's run this class right here so here i'm going to run this with coverage there we go and let me collapse these stats in here and then close all of this go back to the actual service class and now you can see that before this line was red but now it's been covered by our test which is really really cool so there you have it and also you can see that we have covered this test right here this test is fully tested or actually this method is fully tested and the only thing that we have to do is actually test the lead student this in fact will be an exercise for you go ahead and implement the tests for this method right here called the lead student now that we have the student repository and student service both fully tested now we can go and learn about integration testing so as i said before unit testing is about the unit itself right here so we test it in isolation so you saw now we tested student repository in isolation all of the methods then when we tested it within student service right so because here you can see that it's a private field for student service we mark this interaction which means that we also tested this student service in isolation now integration testing is when we test our application as a whole so you can see the boundaries here right so the purple boundaries so basically instead of testing the unit itself right here which is the application as a whole so what we do is we actually spin up the application and then we make sure that the integration between all of the components within our application does work so it means that we actually fire a request into the repository making sure that the api layer is intact and then letting the request flow through the system to make sure that it does indeed work so we no longer need to mock student service nor student repository because this is an integration test so let's learn how to perform integration tests within our application right so we've covered quite a lot to be honest unit testing mocking and you saw how we tested each unit in isolation and yeah so it's not really difficult to be honest once you understand exactly how things are put together we've just scratched the surface i gotta be honest and next what we need to do is actually focus on integration testing so this is where you spin up the application and then you test your api endpoints right so if you have get requests put delete and post then you want to be sending real requests against those endpoints and making sure that the request goes through the system and then does what it's supposed to do without breaking anything so also um the sponsors of this video diff blue they have this awesome integration where you can pretty much just right click and then you can generate a test for your controllers which is really really nice now if you're serious about becoming a software engineer then i do invite you to enroll to both the spring bo full stack and react which this crash course is a mini series of it and also i've got a course just on testing so making sure that you understand the overall picture right so this is where you learn about testing you learn about mocking how to properly write integration tests and also i'm going to show you when you have for example external services such as stripe and twilio and how to properly test those if you are serious about becoming a software engineer go ahead and roll to these two awesome courses they are the best selling courses on my website and i'm waiting for you this is all for now if you enjoyed this video give me a thumbs up subscribe to my channel so i can keep on recording more videos like this and also if you're not part of the amigos code community go ahead and join over 20 000 people already and it's growing like never before so if you need help or you want to share your knowledge i would love you to have you there this is all for now i'll catch you in the next one you
Info
Channel: Amigoscode
Views: 407,333
Rating: undefined out of 5
Keywords: amigoscode, what is software testing, software testing material, java tutorial, junit5, junit, mockito tutorial, mockito, tdd, how to test software, junit tutorial for beginners
Id: Geq60OVyBPg
Channel Id: undefined
Length: 76min 56sec (4616 seconds)
Published: Sun Mar 28 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.