The Best Way To Use Docker For Integration Testing In .NET

Поделиться
HTML-код
  • Опубликовано: 18 ноя 2024

Комментарии • 129

  • @MilanJovanovicTech
    @MilanJovanovicTech  Год назад +4

    Get the source code for this video for FREE → the-dotnet-weekly.ck.page/testcontainers
    Want to master Clean Architecture? Go here: bit.ly/3PupkOJ
    Want to unlock Modular Monoliths? Go here: bit.ly/3SXlzSt

  • @ndanh1
    @ndanh1 Год назад +4

    Finally this day has come! I know once day you will touch this topic. I'm applying this topic on both my side and main projects.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +2

      I'm surprised how many people are excited about this topic, you included 😁

  • @eja7444
    @eja7444 Год назад +13

    Dude, if you ever wrote a book, I got first dibs on it. 😊

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +3

      The course will have to be enough for now 😅
      What should the book be about? 🤔

  • @palashchoudhary112
    @palashchoudhary112 Год назад +1

    Man... I got so many comments saying you should use count 1.... Thanks for clearing the doubts.

  • @watchchat
    @watchchat 8 месяцев назад

    This is a great topic! I haven’t finished the video but the one improvement I’d add is to not have credentials hard-coded in the source. Showing the noobs the correct way to implement that would give them a head start on being a better dev that thinks about security.

  • @ernestmfakudze
    @ernestmfakudze Год назад +1

    Thanks very much for this. I've always struggled with Integration Testing and this clarified it for me.

  • @julienlefevre1661
    @julienlefevre1661 Год назад +6

    Hey, thanks, nice video. Would be also nice to have explainations concerning integration tests in deployed DEV and STAGING environments using CI. Thanks for the job done ;)

  • @nove1398
    @nove1398 Год назад +1

    About time you do this type of video, you need to do more docker work!

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +1

      Any specific topics?

    • @nove1398
      @nove1398 Год назад

      @@MilanJovanovicTech docker compose, if you think it makes sense to you

  • @eziamakanv
    @eziamakanv Год назад +1

    Beautiful! Just Beautiful!

  • @darylbeaumont8855
    @darylbeaumont8855 7 месяцев назад

    This is a great resource and had really helped with integration testing. Thank you for your work covering this topic/technology!

  • @madhu-sameena
    @madhu-sameena Год назад +2

    Thank you for the cool content, This is is really interesting
    I used SQLite or in memory for my API Tests so far, but this is nice.
    It would be great, if you can release one video with calling APIs in tests and also apply the migrations to replicate the real scenario

  • @mbsa220
    @mbsa220 Год назад +1

    Great and informative thanks

  • @porcinetdu6944
    @porcinetdu6944 Год назад

    Very good thank you. I like the explication about the program class at the beginning. Kind of not necessary but making everything super clear

  • @audreyernestodelima7025
    @audreyernestodelima7025 Год назад

    every video is mind blowing

  • @km-9ra
    @km-9ra Год назад +1

    Hey Milan great video, thanks! Is there a way to use the testcontainers package with a CosmosDB? 🙂

  • @benlewies8828
    @benlewies8828 Год назад +1

    Great stuff, Milan. Why not use Selenium IDE for running your web tests (alongside Docker for setting up your infrastructure)?

  • @daauggy
    @daauggy 4 месяца назад

    Just came across a few videos of yours regarding testing. Would love if you done more, maybe a dedicated playlist.
    I see many people talk about integration test for web API’s. But haven’t seen much on integration testing for asynchronous apps (messaging, Kafka etc). Or web apps (ui) - apart from e2e…using web application factory could be useful here also.

    • @MilanJovanovicTech
      @MilanJovanovicTech  4 месяца назад +1

      Talked about it here: ruclips.net/video/ASa8wXMXwrQ/видео.html
      However, I still didn't touch on testing a system that uses a message broker. That'd be a great idea for a video.

  • @majormartintibor
    @majormartintibor Год назад

    Excellent video!

  • @svenscekic2240
    @svenscekic2240 9 месяцев назад

    Great video as always. Just one question does this approach initalize a docker container for each test class or only one container for all test classes?

    • @MilanJovanovicTech
      @MilanJovanovicTech  9 месяцев назад

      It's one container per fixture, not the IClassFixture implementation here: ruclips.net/video/tj5ZCtvgXKY/видео.html
      What does this mean in practice? All tests within a single test class will reuse the same container instances.
      Test cases from different test classes will have different containers.
      You can implement an ICollectionFixture, to share containers across all tests within a collection.
      Or, you can manually create a new container for each test.

  • @wojtas1989
    @wojtas1989 Год назад +3

    Great video Milan!
    One thing bothers me as I see shadowing methods as a huge red flag and problem causer.
    I'm just thinking that explicit interface implementation would be much better here. and if not, then why not to override DisposeAsync with line you've put and call to base implementation?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +1

      Given this is a test class, I think the decision was justified for simplicity. For a more correct solution, your approach is fine 👌

  • @Flanno91
    @Flanno91 Год назад +1

    I think this is one of your most helpful videos yet Milan. Given that once you've done the boilerplate to set this up, it's actually pretty easy to write additional tests, would you say this is a good substitute for unit tests as you don't need to mock anything? Or would you still use unit tests alongside this method?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      I would definitely prefer this over unit test handlers, yes! I'm also writing a newsletter about this right now, and I'll share all the code on GitHub.
      P.S. Thanks a lot! I'm working on improving the quality of the videos after releasing my course, and I'm glad it shows.

  • @AndersChristiansen-s9m
    @AndersChristiansen-s9m Год назад +2

    How does this work without running the migrations on the docker database?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +3

      Migrations are executed at startup in Program, omitted that part

  • @VahidCheshmy
    @VahidCheshmy Год назад +2

    Thanks for the amazing video.
    Just a question, how about using an interface in API and then reference it to the test?
    Something like :
    public interface IMarker { }

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      What would the interface be for?

    • @VahidCheshmy
      @VahidCheshmy Год назад

      @@MilanJovanovicTech in case of using the partial class in program.cs would it also be possible to include this interface in API project and then reference it to test project?
      The interface is just a marker and would be empty.

  • @ВкидимирПодгубенский

    These tests also need something like Respawner library to clear containers db after test execution. Thanks to it a collection of tests can use one container.

    • @pilotboba
      @pilotboba Год назад +1

      Another option is to not put all the tests into the fixture, so it will spin up a container for each test. Of course, this will add overhead and time to your test runs.

    • @ВкидимирПодгубенский
      @ВкидимирПодгубенский Год назад

      @@pilotboba no way , if there are 30 tests - it will start 30 containers!

    • @pilotboba
      @pilotboba Год назад

      @@ВкидимирПодгубенский Maybe. A few things.
      Linux containers are lightweight and fast. So maybe 30 containers isn't a problem.
      You only have to isolate db stuff where one test will conflict with another.
      Another option, write your tests so those data conflicts don't happen. Have each test clean up after itself.
      Id prefer all these before I bring in some tool to clean the db.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      What if each test handles its own data?

    • @ВкидимирПодгубенский
      @ВкидимирПодгубенский Год назад

      @@MilanJovanovicTech every test manages it's data and clear it after execution using Respawner

  • @TrungTran-le2ht
    @TrungTran-le2ht 8 месяцев назад

    Thanks for the content.
    I have a question : what are the Pros and Cons when using TestContainer over the WireMock ?

    • @MilanJovanovicTech
      @MilanJovanovicTech  8 месяцев назад

      WireMock is for API mocking (HTTP) right?

    • @TrungTran-le2ht
      @TrungTran-le2ht 8 месяцев назад

      @@MilanJovanovicTech
      Edit: i just read the document and seems like TestContainers has a wrapper for WireMock but not vice versa.
      yes. I know they are different tools but can we use one to replace another ?

  • @vincentbenazet3137
    @vincentbenazet3137 Год назад +1

    Great Video, I don't understand how you set up your database structure. Does it do it automatically through the DbContext configuration? If I have foundational data, can I use Entity Framework migrations, or do I need to generate an SQL script for that ?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +1

      I run EF migrations at startup (web app factory setup).

    • @pola587
      @pola587 Год назад

      @@MilanJovanovicTech so do you run it after you start async right or how you do it ?

    • @juankar008
      @juankar008 Год назад

      I think is the config that starts at minute 5:30 of the video.

  • @thespicycoder5583
    @thespicycoder5583 Год назад +1

    Great Video.
    When you perform Build & Test inside Docker containers, using test containers might not work.
    As Integration tests are already being executed within a container & you want to spin up a container within a container.
    Any workarounds?
    Thanks

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      Containerception. What environment would you be running that in?

    • @thespicycoder5583
      @thespicycoder5583 Год назад

      @@MilanJovanovicTech Say, Azure DevOps or a Self hosted Kubernetes Cluster

  • @sunnypatel1045
    @sunnypatel1045 Год назад +1

    Great stuff Milan. Had one question is there a way to not use EFCore? I got a project that just uses SqlConnection which calls a store proc and in the settings I am passing only a connection string.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +1

      Sure, why not? Just write some good ol' SQL 😁 Dapper is a good choice.

  • @ross-owen
    @ross-owen 3 месяца назад

    do you have an example video of how to do the DbUp portion of the database? I mean, when it spins up the postgres container, does your image already exist with the schema or is it dynamically running your scripts?

    • @MilanJovanovicTech
      @MilanJovanovicTech  3 месяца назад

      Migrations are ran when app starts in this case. Might be a good idea for a video.

  • @damjantadic
    @damjantadic 10 месяцев назад +1

    Is there a way to specify the build configuration for the container using appsettings?

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад

      Can you be more specific? 🤔

    • @damjantadic
      @damjantadic 10 месяцев назад

      @@MilanJovanovicTech For example the parameters for WithDatabase() WithUsername() WithPassword() I want to get from appsettings.

  • @vekzdran
    @vekzdran Год назад

    Milan, excellent video, I am just working on this setup so video came in perfect time. I missed one thing. I guess the SQL service in the container pings back when its actually started and that signals the StartAsync to have a successful result? Also, I guess, you do DB migrations up in your Program/Startup logic when the factory goes through. I am asking as I need to do exactly this, migrate up a new instance of DB schema at one point and I guess its is OK in StartAsync after container is spinning? Ideas? Thx!

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +2

      Yeah, creating DB is done in Program, I omitted that.

    • @TheDrComedy
      @TheDrComedy Год назад +1

      @@MilanJovanovicTech Is it possible to do a full video on how you created the db schema inside your container?

    • @Capt_stupid
      @Capt_stupid 5 месяцев назад

      @@TheDrComedy That would be super nice

  • @sandroj4585
    @sandroj4585 4 месяца назад

    Hello Milan, thanks for this content. But how do you manage to create the tables automatically in the test container? I tried here and my database couldn't create it. I'm also using migrations.

  • @rareschelariu5327
    @rareschelariu5327 Год назад +1

    How would you approach schema creation and seeding in an app that doesn't use EF (repositories execute raw SQL or stored procedura) ?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +2

      Just run some SQL

    • @rareschelariu5327
      @rareschelariu5327 Год назад

      @@MilanJovanovicTech Of course - managed to do that successfully - I was thinking about structuring of files and versioning, bearing in mind that the TestContainers always points to master DB in the Conn String and regarding SQL SERVER the GO instruction can not be run from remote SQL calls (can not create multiple stored procedures in one statement)

    • @pilotboba
      @pilotboba Год назад

      @@MilanJovanovicTech Is there any way for Testcontainers to use your/a docker-compose file rather than having to define the service containers in code which are already defined in your docker-compose file?

  • @jeanmuyuela8112
    @jeanmuyuela8112 3 дня назад

    can you containerize the api itself for e2e testing? where you can still debug it..

    • @MilanJovanovicTech
      @MilanJovanovicTech  2 дня назад

      How will you hook into it for debugging? I'm not sure that's supported during test execution

  • @SamFugarino
    @SamFugarino 4 месяца назад

    Thank you!

  • @petewarner1077
    @petewarner1077 Год назад

    Great content as usual, Milan!
    I think that dispatching commands/queries directly via MediatR shortcuts the WebApi itself - a key part of the application infrastructure. In that sense, it's not a full integration test because you'll not test logic in the HTTP Middleware (such as Auth) or any code sitting in the endpoint handlers that runs before mediatR.Send
    Would love to see this revisited but using the HttpClient directly to call the API, perhaps including how to (for example) configure the app in testing to expect test bearer tokens.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +1

      I'm fine with bypassing the HTTP request pipeline because there is little value in writing a lot of functional tests. A few of them are definitely helpful, but I think having more integration tests like these is beneficial.

  • @porcinetdu6944
    @porcinetdu6944 Год назад +1

    I am wondering would not it be possible to share the docker instance among all the tests. Each would create a database and not a whole container to save ressources and reduce the overall test time.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +2

      That's a great point. Let me try to find some resources around that

    • @ВкидимирПодгубенский
      @ВкидимирПодгубенский Год назад

      It's possible if use Respawner library and clear db after each test

    • @porcinetdu6944
      @porcinetdu6944 Год назад

      @@MilanJovanovicTech I have been able to do it (with mongo DB using another package to fit my project). I share a singleton using fixture and fixture collection

    • @nove1398
      @nove1398 Год назад

      @@porcinetdu6944 fixture collection creates a singleton?

  • @sasanarham
    @sasanarham 9 месяцев назад

    Thank you Milan for your easy-to-follow videos. Do you have any recommendations for learning best practices in integration tests?
    For example for "Unit Test" I really like this book: "The Art Of Unit Testing" by ROY OSHEROVE

    • @MilanJovanovicTech
      @MilanJovanovicTech  9 месяцев назад

      There could be a book like that, but I haven't read it yet, so can't recommend anything

  • @KenzoArts
    @KenzoArts 6 месяцев назад

    Will the database in the the docker container have the same schema and data that exist in my physical SQL server database?
    In my sql server database i have some sql views and functions that i use in my handlers to fetch data.

    • @MilanJovanovicTech
      @MilanJovanovicTech  6 месяцев назад

      Yes, if you recreate that structure with migration scripts

  • @kostasgkoutis8534
    @kostasgkoutis8534 Год назад

    What about customizing the data inside the container? I see you added a volume, but every test refers to it. Would you tweak them as part of the Arrange section or is there some other strategy you can employ?

  • @ChristopherBriddock
    @ChristopherBriddock 5 месяцев назад

    There should have already been a scoped service descriptor instance of ApplicationDbContext registered, so how did removing just the options class and re-adding the DbContext to the DI container ever work??

    • @MilanJovanovicTech
      @MilanJovanovicTech  5 месяцев назад

      Grab the source code below and give it a try.
      The options are what actually configures the important bits.

    • @ChristopherBriddock
      @ChristopherBriddock 5 месяцев назад

      Sometimes to make it faster, they do just make it work. That might be good in a business situation but personally at home I'd prefer finding out how the errors actually work, instead of making it work.

  • @alpsavasdev
    @alpsavasdev Год назад +1

    Why don't you test against API endpoints instead of Service methods?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      Simpler

    • @alpsavasdev
      @alpsavasdev Год назад

      @@MilanJovanovicTech I see. Besides, you can test the controllers in isolation at the same time.
      One problem I faced with testing API endpoints with test containers is that it fires up a distinct container for each http request even in the same test method so I cannot “get” a database row I just added with a “post” request.

  • @KenB782
    @KenB782 11 месяцев назад

    Are the migrations automatically applied to the container? (Only question I have)

    • @MilanJovanovicTech
      @MilanJovanovicTech  11 месяцев назад

      Yes (at app startup)

    • @KenB782
      @KenB782 11 месяцев назад

      @@MilanJovanovicTech Thank you 😊

  • @matthewrossee
    @matthewrossee Год назад

    What is the difference between minimal api approach and api with controllers in 3:45? How should I do that with controllers?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      Well Program.cs is already public there?

    • @ВкидимирПодгубенский
      @ВкидимирПодгубенский Год назад

      no difference - just write this line in your program.cs

    • @pilotboba
      @pilotboba Год назад

      @@MilanJovanovicTech Not if you use top level statements with controllers. You still need to add the partial public visible class afaik.

  • @muumitramm
    @muumitramm Год назад +1

    Why should i use temporary database if i just could use Moq to mock the database. No need to spin up anything. :)

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      Because you might as well be using in-memory data. Why even have a database?

    • @muumitramm
      @muumitramm Год назад

      @@MilanJovanovicTech yeah. That was my idea but tests are calling methods that have db queries inside. Those should be mocked as well.