Sharing Top Content from the Angular-sphere.

Angular testing made easy – Clarity Design System – Medium

“Angular Testing Made Easy” by @EudesPV  #angularjs #javascript #typescript #testing #coding

  • TestBed configuration, compiling the components, creating the one you need, getting access to the directives instances, cleaning up, … And if you are working on a real-life project, you probably have many spec files across your code base, all needing the same boilerplate.
  • There are two main advantages to this approach over local variables: it helps fight the memory leaks that keep creeping up on large projects’ tests, and it also offers a very easy way to have your beforeEach and it in two different files, which is much harder to set up with local variables.CAUTION: We are using a plain function() {} here, rather than the very useful () = {} arrow notation from Typescript.
  • One of the recommended patterns (and the one we use the most, by far, in Clarity) is to use a “test host” component which includes the actual component to test in its template:This example makes a few assumptions to keep it simple: the templates are all inline or inlined at build time so we don’t need to MyUserComponent doesn’t depend on other components, … Feel free to adapt to your specific use case.Introducing the TestContextIf we want to extract all the boilerplate into a separate file, we need to decide what the type of the user context passed around by Jasmine should be.
  • The one difference is that we’re getting the tested directive through the injector, rather than componentInstance, once again to be able handle attribute directives and components at the same time.The final spec fileLet’s remove all the boilerplate from the user component’s spec file and use our brand new context:It’s now entirely comprised of the unit tests, no distractions or verbose setup to go through.
  • That’s a win!To improve this further, you could easily:include the setup() call at the root of the tests to have it always be available,allow passing extra directives to declare or modules to import, in case your component depends on other ones,add additional shortcuts to the TestContext interface,throw explicit errors when trying to test with a host component that does not contain the directive,…In our case, for instance, we have a shortcut to get providers from the tested element’s injector.

If you’re here, you have probably already read the Angular documentation on testing, and maybe have written a few tests for your own project. If you have not, I can only suggest you do so, because…

@K0YCHEV: “Angular Testing Made Easy” by @EudesPV #angularjs #javascript #typescript #testing #coding

Now, if you’re still interested in the original article, feel free to go on.

If you’re here, you have probably already read the Angular documentation on testing, and maybe have written a few tests for your own project. If you have not, I can only suggest you do so, because this article will require some prior knowledge of Angular testing.

configuration, compiling the components, creating the one you need, getting access to the directives instances, cleaning up, … And if you are working on a real-life project, you probably have many spec files across your code base, all needing the same boilerplate. So what’s the most efficient way to centralize that boilerplate, so that your actual spec files can focus on the unit tests themselves?

. We’ll round it up by relying on some “advanced” parameterized typing to make sure everything is truly reusable.

to the same object when running a test? This object allows you to share information across the different phases of your test, and the object gets properly destroyed at the end of each test to avoid memory leaks.

So what does that look like? Here is a simple example:

in two different files, which is much harder to set up with local variables.

, so you will not get any form of autocompletion, type checking or smart navigation in your IDE.

as if it were an argument of the function:

Doing so will give you back of the advantages of Typescript’s strict typing, including compilation errors when accessing unknown properties or autocompletion in your favorite IDE:

Let’s apply this to testing a component in Angular, for instance to check if a two-way binding works properly. One of the recommended patterns (and the one we use the most, by far, in Clarity) is to use a “test host” component which includes the actual component to test in its template:

doesn’t depend on other components, … Feel free to adapt to your specific use case.

method that will handle all this. Then of course, we’ll want access to all the queried native elements and component instances, so we’ll need to expose these too. Using type parameters to make sure it can work on any directive to test and any test host wrapping it, we obtain this:

, the reason being that we might sometimes be testing attribute directives instead of components, so the more “general” denomination makes more sense.

that should be called before anything else:

, and we make sure created fixtures are destroyed after each test. Suddenly, most sneaky memory leaks that would happen because of one spec forgetting to clean up are handled!

, once again to be able handle attribute directives and components at the same time.

Let’s remove all the boilerplate from the user component’s spec file and use our brand new context:

and you’re ready to go!

No more boilerplate in all spec files, no need to remember teardown to avoid memory leaks, and a single place to update when the testing API of Angular changes. That’s a win!

To improve this further, you could easily:

In our case, for instance, we have a shortcut to get providers from the tested element’s injector. That’s a great way to test communication between our components. Go crazy, and feel free to comment with your own awesome helpers!

Angular testing made easy – Clarity Design System – Medium

Comments are closed, but trackbacks and pingbacks are open.