Spring Boot Testing Basics: How to Unit Test & Integration Test REST Controllers

Sdílet
Vložit
  • čas přidán 7. 09. 2024
  • In this tutorial, I want to discuss some basics of testing a rest controller in a Spring Boot application. This came up because of a tweet I sent out recently asking developers to stop calling a certain test a unit test. The reason I said this is because whenever you start involving Spring and the whole request & response lifecycle its no longer a unit test. In this demo, I will create a new Spring Boot application, create a simple rest controller and then show you how I would Unit & Integration test that controller. If anything this is just meant to spark a discussion so I would love to hear your thoughts on the subject.
    When you have completed this tutorial you should understand:
    ✅ Create a new Spring Boot Application
    ✅ Create a new Spring Boot Rest Controller
    ✅ Create a Unit Test
    ✅ Create an Integration Test
    ✅ Run a basic test in a Spring Boot Application
    ✅ How to use JUnit 5 in a Spring Boot Integration Test
    🔗Resources & Links mentioned in this video:
    Source Code: github.com/dan...
    Martin Fowler Unit Test: martinfowler.c...
    👋🏻Connect with me:
    Website: www.danvega.dev
    Twitter: / therealdanvega
    Github: github.com/dan...
    Instagram: / thedanvega
    LinkedIn: / danvega
    Coffee & Code: www.danvega/de...
    SUBSCRIBE TO MY CHANNEL: bit.ly/2re4GH0 ❤️

Komentáře • 115

  • @DanVega
    @DanVega  Před 4 lety +10

    What is your definition of a Unit & Integration Test?

    • @Anbu_Sampath
      @Anbu_Sampath Před 4 lety +4

      I agree with your definition of Unit and Integration Test. For Controller and Data layer, spring boot gives nice mock to test actual annotation and spin up minimal context. Because those layers we are not keeping much business logic.

    • @pvrsouza
      @pvrsouza Před 4 lety +10

      I really never understood why using Unit Test on controllers. For each request a controller usually does a lot of steps like deserialize, validate, translate exceptions, etc its almost impossible do cover that on Unit Tests. IMHO, Unit Tests on controller (http layer) is just to verify business logic has been called and i can't see relevant value on it. Maybe i'm wrong but I really believe it's better build just Integration Tests for HTTP layer.

    • @Cassio81863636
      @Cassio81863636 Před 3 lety

      @@pvrsouza I agree with you. Usually in projects I work with, Controllers are only tested in Integration tests. and kinda solves coverage so

    • @handsome_man69
      @handsome_man69 Před 2 lety +4

      There is no hard line between a Unit Test and an Integration Test. If you wanted a pure unit test then you would have to mock every external dependency, which would mean even mocking "String" objects. SUddenly It gets completely absurd. I have been in projects where they have written tests that are about 20 lines long, and that have tested exactly ONE line of code. The value of tests like this are next to ZERO. In my opinion unit tests are generally useless, unless you need to test complex algorithms or things like utils methods like DateUtils and that kind of thing. As soon as you start mocking too much you get tests which have no value. Integration Tests are much better because they more closely resemble Use Cases. As long as the performance/speed of these tests is good (TIP: use in memory databases!!!!! ), then you should focus on them over unit tests. Writing a test that goes from the RestController to the DB is excellent. It perfectly captures a Use Case. As long as the performance is fine..... do it like that!!!!!

    • @g.v.m7935
      @g.v.m7935 Před rokem

      Isnt the @Test a spring notation? Refering to the start of the video where you said spring wasnt involved yet. Just out of curiosity so I know if I understand spring well enough in the basics.

  • @khalilgreenidge981
    @khalilgreenidge981 Před 3 lety +47

    I literally spent 5 hours trying to achieve this. At 2 am I found your video. Thank you so much!

  • @shashidhar71
    @shashidhar71 Před 3 lety +11

    Your definition is right. Unit - Single entity.
    Integration - How it works with entire system.
    Imagine if you have missed @RestController annotation, unit will pass but int fails.

  • @brianocorner5604
    @brianocorner5604 Před 3 lety +2

    WoW..!! Dan!!! Thanks for sharing an amazing tutorials and good explanation. It is 4:00am here. Thanks to you, my searching ends here.

  • @haroonafridi1802
    @haroonafridi1802 Před 2 lety +1

    100% agree with your thoughts about unit testing and integration testing

  • @stephaneislistening6103
    @stephaneislistening6103 Před 3 měsíci

    I could use this AutoConfigureMockMvc testing with your other Testcontainers you gave us in another video. Thanks Dan !

  • @catsbite3634
    @catsbite3634 Před 2 lety

    It’s 5:17 am and I found this. Thanks for ur video

  • @FellTheSky
    @FellTheSky Před 3 lety +1

    This is the best video about testing. Watched so many but yours let everything clear! (im junior)

    • @DanVega
      @DanVega  Před 3 lety

      Wow, thank you! That is a great compliment. Is there anything else in testing you would like me to cover? I should have a video on Spring Data Slice Testing coming out this week.

    • @FellTheSky
      @FellTheSky Před 3 lety

      @@DanVega Well usually every video has details of how to create a rest controller or other types of controllers. I get that, but when you apply for a junior job, they assume you already know testing. Thats not the case.
      I have a controller that returns a DTO with this format: {"idUser":0,"email":null,"firstName":null,"lastName":null,"loans":null}(loans is a list)
      Well i have no idea of how to test it. Should i recreate the entire method in the test class? I dont think so because in that case whats the difference with just using postman.
      Maybe this sound dumb to you, but ive started to code 6 months ago, and right now im applying for spring junior dev (fintech). They want me to know: ORM, Spring Boot, SQL, Hibernate, GitHub, Maven, testing and logs.
      I think 1 minute at the end of the explanation quickly showing how to test it would be great, but i get it, thats a low of added work.

    • @batasheemum
      @batasheemum Před 3 lety

      Dan Vega It would be great if you can do basic spring boot testing videos for junior automation testers/developers etc.

    • @batasheemum
      @batasheemum Před 3 lety

      Would be grateful

  • @natetolbert3671
    @natetolbert3671 Před 3 lety +5

    I may be wrong about this it's been a while since I've "looked under the hood" in spring, but doesn't the spring framework, as soon as it sees the at test annotation, create its own mock dependency. I'm thinking that I remember it marks the entire environment so that it can run the tests.
    Also one key point about integration tests just because a test _includes_ integration (via stubs,mocks, etc) that doesn't make it an integration test. When you write a unit test that contains mock dependencies on neighboring classes, you're not writing assertions to check that those integrations are working as intended, as you would in an integration test. in fact, with mocks the integration isn't even there. The entire point of frameworks like makito is to take the 'integration' factor out of the dependencies.
    In summary, the point I'm trying to make is that while unit tests may contain dependencies, and occasionally with third-party dependencies, may even contain integration, integration tests actually test said integration and fail if it doesn't behave as expected. Just my two cents. Have a great day.
    Btw, have I commented on this video before? This whole thing is feeling eerily deja Vu to me...

  • @abeplus7352
    @abeplus7352 Před 4 lety +6

    Thank you ! I had an argument the other day with one of the devs about unit testing in go lang . spinning up an entire http server to just do a controller test is stupid that's an integration test not unit .

    • @natetolbert3671
      @natetolbert3671 Před 3 lety +1

      As I said above, it doesn't depend on what you're running in a test it depends on what you're testing. You can start up the whole damn application and call every single method in your unit, but if you're assert methods are only testing the functionality inside your unit, in this functionality is not being changed by anything else that is happening, it is still just a unit test. One more time, just for clarity, to be an integration test, it has to __test__ that the units are integrating as expected, and fail if they are not. Otherwise it is just a unit test. Simple as that.
      If we're going to start naming tests based on what they include, then by this logic, every test is a unit test because they all include units...

    • @abhishekpal7291
      @abhishekpal7291 Před 2 lety

      I have spent a whole night on this thing!

    • @abhishekpal7291
      @abhishekpal7291 Před 2 lety

      @@natetolbert3671 But my teammates are checking the be rest controller just as an normal classs i.e. calling method and asserting the return value without worrying about checking get/post mapping. Should I go with mockmvc or just normally test like others have done.

  • @nguyentoan9012
    @nguyentoan9012 Před 3 lety +6

    I solved the problem " java.lang.IllegalStateException: Failed to load ApplicationContext" by repacing 2 annotations of the test class with @SpringBootTest
    and @AutoConfigureMockMvc.

    • @Wegman7
      @Wegman7 Před 3 lety +1

      I'm new to Java and I have no idea why this works/ how it's different, but this worked for me too lol.

    • @rabiebelkaida
      @rabiebelkaida Před 2 lety

      Thank you bro it's worked well :)

  • @arjungupta4672
    @arjungupta4672 Před 3 lety

    Quick and fast way to understand difference and learn 👍

  • @procrastinator24
    @procrastinator24 Před 2 lety +1

    Nice and clean explanation, thank you!

  • @raphaelzamora7974
    @raphaelzamora7974 Před 2 lety

    thank you for this! I’m supposed to be writing a unit test before I move on to integration testing and it seems like I jumped the gun

  • @muluadamtemesgen5993
    @muluadamtemesgen5993 Před 2 lety +2

    That is very interesting, could you make some video on how to test services and repository ?

  • @ChildrenOfDemiurgos
    @ChildrenOfDemiurgos Před rokem

    Plain and simple. Thank you! Awesome if you could make a more in depth video about this.

  • @saeidkazemi8480
    @saeidkazemi8480 Před 3 lety

    Thanks a millioooon for the great explanation and illustration

  • @joshuaecht
    @joshuaecht Před 4 lety

    CLEVELAND! Go Browns! :) This is a great vid. I went to We Can Code IT and we learned this, but it helps refresh my learning of Testing.

  • @taprandich
    @taprandich Před 3 lety +1

    Thank so easy to understand would be nice if you advance this topic on the more complicated methods as well

  • @mateovansweevelt5257
    @mateovansweevelt5257 Před 2 lety

    What an absolute beautiful video man!

  • @johnvoorhees2331
    @johnvoorhees2331 Před rokem

    I just found our videos 2 weeks ago(Love them) Would it be possible to show how to create proper JUNITs over the Spring Repo Layer. A lot of mocking and i get confused

  • @teotsi21
    @teotsi21 Před 4 lety

    Great video, couldn't figure out the Integration Testing, thanks!

  • @emaayan
    @emaayan Před 3 lety +2

    as far as i know unit tests are designed to test application logic, so if you unit tests a controller that means you have application logic inside a controller which as far as i know , is a big no no.

  • @rawdiarieswithsunil
    @rawdiarieswithsunil Před 3 lety +1

    Pretty clear.. can extend the video series for writing integration for Mapper, Converter, like all different models..? That will clear all the stuff..!

  • @foruvasanth
    @foruvasanth Před 2 lety +1

    question on integration tests - Whats the best practice if this endpoint need to fetch data from database, do we spin up in memory like H2 or hit the db by running these tests in Dev??

  • @jacsdev
    @jacsdev Před 2 lety

    thanks for sharing this kind of content!

  • @aceisastud
    @aceisastud Před 3 lety

    Love this video BUT love the shirt even better! Go Browns! From a fellow Ohioan to another thanks for the videos!

    • @DanVega
      @DanVega  Před 3 lety

      OH- Thank you Chad! I actually made that shirt myself. I have a bunch of Browns shirts so I will try working them in.

  • @ildar5184
    @ildar5184 Před 5 měsíci

    It feels like the distinction between unit and int tests is fuzzy. Because there're different levels of how many levels of your system you can include in your tests. The easiest scenario, when you test just one component, with its integrations with other components replaced by mocks, is unit testing, that's pretty much clear.
    For integration tests, you can test any level of integration, from the simplest, like just plugging the web framework as in your example, and still mocking stuff like database and calls to other microservices, up to spinning up your entire ecosystem, with all layers included, e.g. locally via docker and test containers. Are these types of testing all integration tests? What I've got is that it's still a matter of debate, some people consider the first type (like in your example) to still be unit testing. And I guess the reason for the debate is that it kinda has features of both.

  • @kekiir
    @kekiir Před rokem

    Cool to make the first step by step part (Request builder request...., MvcResul result...., assertEquals(...) with this is much more understandable the code after mvc.perform....

  • @mykyta1235
    @mykyta1235 Před rokem

    It does not matter what you think of the component or unit , it doesn't matter if you don't count it as valuable.
    Integration tests - tests for the stand alone components interaction between their public interfaces.
    Unit tests - are tests for the smallest testable parts of the application.
    That's it.

  • @kaiser92600
    @kaiser92600 Před rokem

    Thank you for your tuto, very good work

  • @luvcode567
    @luvcode567 Před 3 lety

    Really nice one. It helps in understanding the between unit test and integration test. can you make more videos on integration test. Also looking for test using Mockito

  • @Utub-qc2cz
    @Utub-qc2cz Před rokem

    Thank you Dan for this content. Would you please share your experience with more advanced examples of integration tests using DdUnit ?

  • @somtovitus
    @somtovitus Před rokem

    this is beautiful, thank you

  • @legacylifey182
    @legacylifey182 Před 2 lety +1

    Thank you so much!

  • @shakib_04
    @shakib_04 Před 2 lety

    you missed a thing at 10:50 , wheren webmvctest annotation does not create bean for @component , service and reporsitory

  • @enesb4797
    @enesb4797 Před rokem +2

    Hello, I don't have the get() method in 14:55. When I click "Import static method" it gives me lots of methods to choose.

    • @DanVega
      @DanVega  Před rokem +1

      I often am confused on where this is coming from as well. Here is the static import for that
      import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;

    • @enesb4797
      @enesb4797 Před rokem

      @@DanVega thank you so much!

  • @ABHISHEKMISHRA-ib5vo
    @ABHISHEKMISHRA-ib5vo Před 3 lety

    Grear Dan! 😊

  • @manuellarrota
    @manuellarrota Před 3 lety

    Gracias mi pana, muy bien explicado un abrazo!

  • @dadams1989
    @dadams1989 Před 2 lety +1

    Where did you get your shirt? Love it!

    • @DanVega
      @DanVega  Před rokem

      I actually made that myself when I briefly got into the t-shirt side hustle game 🤣

  • @MarkGallo-tt8pt
    @MarkGallo-tt8pt Před 3 lety

    My assert equals fails because of the URI returns empty with body = null. When I do a get command from the URI it does show me the string I would want to compare but it doesn’t work for the assertEquals

  • @diegoramos27
    @diegoramos27 Před 2 lety +1

    Hi Sir why do we need to add HelloController.class inside the @WebMvcTest? is this annotation not capable of doing component scan aromatically thanks ?

    • @DanVega
      @DanVega  Před 2 lety

      You don't have to but if you to avoid scanning and be specific it could help performance in a larger app

  • @aussieclicks96
    @aussieclicks96 Před 4 lety +2

    Thank you

    • @DanVega
      @DanVega  Před 4 lety

      Thank you for watching!

  • @VISITLosAngeles
    @VISITLosAngeles Před 3 lety

    Thank you so much sir :)

  • @smaug9833
    @smaug9833 Před 3 lety

    Hey could you show us how to test REST mappings that must pass through Spring security configuration?

  • @JuanCamiloGutierrezFuentes

    thanku man i love u

  • @mtc539
    @mtc539 Před 2 lety +3

    Hi Dan, great video. Is it fair to assume that these kinds of integration tests involving the Spring components ie. @WebMvcTest are excessive? I'm sure the Spring devs test their own MVC-related components, so aren't we just testing something they're already testing themselves before making releases of their libraries? If my assumption is correct here, then is the unit test you made at first in this video all that is needed to ensure the code that YOU wrote is working properly?
    I'm still very new to TDD in general and I'm trying to wrap my head around some of these scenarios and would love your input here.
    Thanks! -Matt

    • @handsome_man69
      @handsome_man69 Před 2 lety +1

      no because the WebMvc test is testing the request parameters you are defining in the rest controller method. This logic cannot be covered by a vanilla test.

  • @Kubakaiser
    @Kubakaiser Před rokem

    If you test the whole Spring application, with the *@SpringBootTest* , without mocking any beans, is it called an integration test, or acceptance test?

  • @HazemAls
    @HazemAls Před 3 lety +1

    wow thanks

  • @armanhosyan5660
    @armanhosyan5660 Před 2 lety

    Thanks a lot.

  • @n3x4r3
    @n3x4r3 Před 3 lety

    But how can do an integration test when my micro service use other 2 micro service to get me a response ? I have to mock the response from the others micro services ? or what , I have a huge doubt about it

  • @livb4139
    @livb4139 Před 3 lety

    Is this integration test or unit test? Should you split both on their own folders or something?
    Do you have a video like for testing this but also using a service and a repository to do stuff with a db?

  • @EdsonLima-hp6ew
    @EdsonLima-hp6ew Před 11 měsíci +1

    nice :)

  • @FilipCodes
    @FilipCodes Před rokem

    What is the difference between unit test and component test?

  • @huhuboss8274
    @huhuboss8274 Před 4 lety +2

    I always get "java.lang.IllegalStateException: Failed to load ApplicationContext" :/

    • @Next80sProject
      @Next80sProject Před 4 lety

      maybe you need to add your base package to the @SpringBootApplication(scanBasePackages = "your.base.package") int the UnitVsIntApplication class.

    • @nguyentoan9012
      @nguyentoan9012 Před 3 lety +2

      I solved that problem by repacing 2 annotations of the test class with @SpringBootTest
      and @AutoConfigureMockMvc.

  • @Das.Kleine.Krokodil
    @Das.Kleine.Krokodil Před rokem +1

    In what cases in tests does it make sense to use a web server, and not MockMvc?

    • @DanVega
      @DanVega  Před rokem

      Thank you for the question. When you want to do a true end to end test and simulate a production like environment I would use a web server.

    • @Das.Kleine.Krokodil
      @Das.Kleine.Krokodil Před rokem

      @@DanVega thanks a lot

  • @demidrek-heyward
    @demidrek-heyward Před 3 lety +1

    thanks!

  • @marcop.7278
    @marcop.7278 Před 2 lety

    So how do you test when you return JSON and you want to test that e.g. variable message of this JSON contains a String, without asserting it to a String per se?
    I'm asking because I'm doing tests where the content of the String is random and cannot be guessed beforehand, we just know it should not be null.

    • @DanVega
      @DanVega  Před 2 lety

      Do you have an example or could you post one on Github where I could take a look at this?

  • @sarramerabet2611
    @sarramerabet2611 Před 4 lety

    thank you so much

  • @manufactured_reality
    @manufactured_reality Před 3 lety

    Do you see any benefit in doing both unit tests and integration tests with mockito?

  • @xmo3608
    @xmo3608 Před 4 lety +2

    Isn`t @ExtendWith already included by @WebMvc?

    • @DanVega
      @DanVega  Před 4 lety +1

      I believe it is now, yes. You can always cmd or ctrl+click the annotation to take a look.

  • @Das.Kleine.Krokodil
    @Das.Kleine.Krokodil Před rokem +1

    Does this mean that the controller cannot be unit tested?

    • @DanVega
      @DanVega  Před rokem

      It can be..my question to you would be if you wrote a unit test for that controller what value would it be giving you?

    • @Das.Kleine.Krokodil
      @Das.Kleine.Krokodil Před rokem

      @@DanVega Possible shorter execution time.

  • @apritellolives3920
    @apritellolives3920 Před 2 lety

    Thats how I feel, I feel integration and e2e testing is more valuable than unit testing especially if you developing an IT website that pretty much just manages and displays data.

  • @JafarAli-ly1ue
    @JafarAli-ly1ue Před 4 lety +1

    what about service layer unit testing??

    • @DanVega
      @DanVega  Před 4 lety

      The service layer could mean different things to different people. What are you trying to test in your service layer?

    • @northdankota
      @northdankota Před 3 lety +1

      ​@@DanVega if our service layer talks repository and controller layer, wich testing should we do unit ? integration ? or both?

    • @hurle0409
      @hurle0409 Před 3 lety

      @@northdankota Yeah this is real life scenario. But can't find useful test case for it. Did you find?

    • @northdankota
      @northdankota Před 3 lety

      @@hurle0409 i am not sure actually, which or why to choose these options

  • @AmNotLegend
    @AmNotLegend Před 3 lety

    @ExtemdWith(SpringExtension.class) is redundant

  • @handsome_man69
    @handsome_man69 Před 2 lety

    There is no hard line between a Unit Test and an Integration Test. If you wanted a pure unit test then you would have to mock every external dependency, which would mean even mocking "String" objects. SUddenly It gets completely absurd. I have been in projects where they have written tests that are about 20 lines long, and that have tested exactly ONE line of code. The value of tests like this are next to ZERO. In my opinion unit tests are generally useless, unless you need to test complex algorithms or things like utils methods like DateUtils and that kind of thing. As soon as you start mocking too much you get tests which have no value. Integration Tests are much better because they more closely resemble Use Cases. As long as the performance/speed of these tests is good (TIP: use in memory databases!!!!! ), then you should focus on them over unit tests. Writing a test that goes from the RestController to the DB is excellent. It perfectly captures a Use Case. As long as the performance is fine..... do it like that!!!!!

  • @johnborys9868
    @johnborys9868 Před 2 lety

    When does anyone ever instantiate a controller in production code? You're righting a test for a scenario that will never occur. This "unit" test seems redundant and totally without value. You are testing your string concatenation. (Logic). A controller should not have business logic. It should delegate that to the service layer.

  • @robertpeschke7746
    @robertpeschke7746 Před rokem +1

    Sorry, but your background music is so annoying and distracting.

    • @DanVega
      @DanVega  Před rokem

      Agreed it can be. I was trying new things 🤷‍♂️

  • @zaycef03
    @zaycef03 Před 3 lety +1

    That is one useless video.. does not explain what to do with service and DAO dependencies..

    • @DanVega
      @DanVega  Před 3 lety +11

      Sorry this video didn't meet your expectations but let's discuss your comment. This video wasn't met to cover everything you need to know about writing unit and integration tests. This was simply my thoughts on the two types of test and how the lines are blurred.
      If you're interested in seeing me create a tutorial on what to do with service and DAO dependencies in a certain type of test this would have been a much better comment "Thanks for the tutorial Dan... I am a little confused on what do with my service and DAO dependencies in a unit test, any chance you can break that down for me."

  • @muditshukla
    @muditshukla Před 2 lety

    Great explanation. Thank you Dan