Angular Unit Testing | TOP 5 Mistakes to Avoid

Поділитися
Вставка
  • Опубліковано 14 гру 2024

КОМЕНТАРІ • 41

  • @DecodedFrontend
    @DecodedFrontend  Місяць тому +2

    Explore all the potential of WallabyJS 2.0 with a free trial 🚀
    wallabyjs.com/?referrer=DecodedFrontend2024
    🔥 Angular Unit Testing Course - bit.ly/angular-testing-course

  • @theanswer1993
    @theanswer1993 Місяць тому +10

    Nice. Looking forward to more videos about testing :)

  • @chekitdnb
    @chekitdnb Місяць тому +2

    Thank you very much for reviewing such important topic. I wanted to add my 5 cents. 😅
    For the last case with subscription to the Observable we can also utilize a done function, which will should be called within a subscription after expect block. In this case test will wait untill the done function is called, thus the assertion will be executed and only after that the test case will be considered as executed. I found writing tests this way with some asynchronous tasks makes you more in control of the flow and makes it more explicit on when it is really considered as "done" 😉

  • @SamuelAlejandro-f6t
    @SamuelAlejandro-f6t Місяць тому +1

    Thank you! Nince hints! You never disappoint

  • @AlainBoudard
    @AlainBoudard Місяць тому +2

    I love your content, great value !
    About testing only the "class", I think it's not useless, especially if you have an e2e testing strategy.
    Shai calls it isolation tests, and no it will not test the whole application, but honestly, no tests will.

    • @DzikiMoronHackshield
      @DzikiMoronHackshield Місяць тому

      Yes, we can have test which tests logic of this particular method and another one which tests the whole flow

    • @DecodedFrontend
      @DecodedFrontend  Місяць тому

      Hi Alain,
      Thank you for your comment and your kind words about my channel :)
      Could you please clarify what do you mean by "e2e testing strategy"? Because my understanding of "e2e strategy" is when you are testing entire application including all dependencies, backend, network, etc. and fairly speaking I don't get how class-only tests fit this concept. To me it doesn't even sound technically possible :) But maybe I am missing something or did you mean something else?
      I can not speak from Shai, but I believe by saying "isolation tests" he means "unit tests" because usually these 2 terms are used interchangeably. Yes, isolated (unit) tests indeed do not test whole application, and they must not to do that because it is responsibility of e2e tests. Unit tests verify only the behaviour of 1 single unit (component/directive/pipe/etc) assuming that unit dependancies are working as expected. On practice we achieve that by mocking dependencies. In e2e tests we mock nothing and test everything as it is. This is the whole difference. The important take, however, is that in both type of tests we should simulate behaviour/interaction of user as close as possible to make the tests reliable and this is exactly what class-only unit tests fail to do because they lack of that interaction layer.
      I hope I could make it a little bit clear :)

    • @AlainBoudard
      @AlainBoudard Місяць тому

      @@DecodedFrontend Yeah, sorry for the confusion, I didn't mean that we would make e2e tests through our unit tests.
      I mean : if you have some e2e tests in your app, and they can be in an integration environment, maybe even with mocked api, you could skip probably completely the DOM tests in your unit tests. Then you could focus on testing your algorithms, all the pure functions that exist in your components and services and pipes, whatever.
      I like the class testing for angular components because I think that most of the time, the user actions are very "partial", when you test a single component, so many things happen that never come from the user actions, or maybe very indirectly.
      I hope I myself am a little bit clearer :)
      Anyway, I like to see other strategies, because these concepts and technologies keep evolving !

  • @eduardserei6859
    @eduardserei6859 Місяць тому

    Amazing content as always! ❤️🔥 just my two cents:
    Mistake #1 is not necessarily a mistake, it's a preference or a safety measure. We could work around it by either creating a function to get new instance of the object on each call or use spread operators to copy the object and change only the properties needed or assign the value of the object on beforeEach. The real issue is not handling immutability principle properly.

  • @FirstLast-i7j
    @FirstLast-i7j Місяць тому +1

    Insightful video💡. All the tips are practical and helpful.

  • @rryter
    @rryter Місяць тому +1

    Great Content, appreciate it!

  • @TheSysmat
    @TheSysmat Місяць тому +1

    Great as always 🎉

  • @informer9261
    @informer9261 Місяць тому +6

    make an video of ngrx signal store & how to make api calls with in it with help of rxjs functionalites

  • @rahultej8352
    @rahultej8352 Місяць тому +1

    Great explanation

  • @yamillanz8244
    @yamillanz8244 Місяць тому +1

    Completely agree with the mistake 3

  • @ВиталийЛиткевич
    @ВиталийЛиткевич Місяць тому

    Thanks for the video! If you had an Angular project that currently doesn't have any tests, would you choose Jest or Jasmine? Is Jest ready for use now, or is it better to stick with Jasmine for the time being?

  • @ChessPuzzlesVideo
    @ChessPuzzlesVideo Місяць тому +2

    For 5th mistake, we handled it using Jasmine done callback. But your solution is much more better and easy.

    • @larshanisch
      @larshanisch Місяць тому +1

      The "done" callback would be better, if there's some async stuff going on in the background or implementation of the output.
      Great video as always!

    • @DecodedFrontend
      @DecodedFrontend  Місяць тому +3

      Thank you for your comment :) I would actually argue if done,() would be a better solution :) done() will block the execution of tests until it is called. If it is never called, the test will fail only after some timeout 5/10/20 secs which is not good because you want tests failing asap to not waste resources of your CI pipeline. If async stuff is involved, I would probably go with something like fakeAsync :)

    • @larshanisch
      @larshanisch Місяць тому +1

      @@DecodedFrontend do you have some material on fakeAsync, waitForAsync etc.? I'm not very confident in using them. I've seen them and know the documentation, but my knowledge can be improved... 🥸

    • @DecodedFrontend
      @DecodedFrontend  Місяць тому +1

      As free material, unfortunately, no :( But maybe I will do in the future :)

  • @jbuiquan
    @jbuiquan Місяць тому

    Thanks for the video, I really like your content, very insightful !
    For mistake 3, wouldn't it bloat your code and rendered html with testId data attributes ?

  • @dimitritsikaridze6220
    @dimitritsikaridze6220 Місяць тому +1

    I opened your testing course from comments and description of this video and it says "Invalid coupon code"

    • @DecodedFrontend
      @DecodedFrontend  Місяць тому +1

      Yeah, indeed something went wrong. You can try this link - bit.ly/course-angular-testing
      Link in the description was also updated. Sorry for inconvenience

  • @georgeknap2631
    @georgeknap2631 Місяць тому

    About n.4 you presented it on a piece of code where it actually make sense. However, for private methods that are called by public methods that are being invoked by some UI interaction, does it make more sense to have bigger "integration" test of all (ui-public-private) or just "unit" test of that private method? I would have both and I would even prefer to have 3 tests for each part.

  • @haroldpepete
    @haroldpepete Місяць тому +1

    great video thank Dmytro, the last test confused me, you're subscribing and then you change the value inside the function, subscribe is like a promise, how can you make the assertion in the last sentence?

    • @DecodedFrontend
      @DecodedFrontend  Місяць тому

      Hey Harold,
      this is a great question. The thing is that outputs are synchronous which means that .subscribe(…) will be executed as part of the emit() method call stack, so that’s why the execution will be in the order that is slightly different from how it is written in code.

    • @haroldpepete
      @haroldpepete Місяць тому

      @@DecodedFrontend ok, thanks

  • @barmooj
    @barmooj Місяць тому

    Could you compare when is it better to have an input per property vs a single input containing an object with all properties inside? In your sample code here you used the latter; single input passing data object

  • @PauloSantos-yu1tn
    @PauloSantos-yu1tn Місяць тому

    Subsribe inside tests could lead into problems in CI pipelines if those observables relies on time. I prefer using marbles in these cases, much clear and simple.

  • @coolfire0001
    @coolfire0001 Місяць тому +1

    I would freakin' love more videos about testing with angular, maybe with some complex scenarios as well,
    Like dealing with a combination of observables, promises and timers with services.
    Also in the project that I work on I developed a master detail component which has a form on 1 side as a component and another separate component on the detail side which is opened with a keybord shortcut, and has a interactive grid, I'm not sure how will I go about testing this type of stuff.. 😁

    • @DecodedFrontend
      @DecodedFrontend  Місяць тому

      Thank you for your comment :) Hard to say something concrete about your use case without seeing the component itself :( Just as a idea to make integration tests if those 2 components are working as "one system". But again, it is just an idea/thoughts.

  • @straker_741
    @straker_741 Місяць тому

    Totally agree on mistake 4

    • @andyt6710
      @andyt6710 Місяць тому

      In my projects, customer often allocates a small amount of CPU and RAM for CI. Because there is a queue of unit tests (all resources are occupied by running tests) among the created merge requests, you need to wait-in my case, it can take 4-5 hours-for your MR (Merge Request) to pass the pipeline. I think one of the reasons is that we are not invoking class methods directly but are doing it through the UI.
      From my point of view, what does it change, if we delete in html a method invocation?

    • @andyt6710
      @andyt6710 Місяць тому

      Moreover, in production code our component contains a lot of child components and as a result we must initialize children to invoke a method in our parent component.

  • @marcwinner567
    @marcwinner567 Місяць тому

    Slava Ukraini!