Best practice to test your Angular directive and component

Testing is never useless, especially in JavaScript world where the language is dynamically typed, there is no excuse for not testing. If you are not writing test for your code, sorry it is too late. If you are, do not be satisfied too early because most unit testing is wasted.

In OpenPaaS project, we write a lot of tests, and of course we do not want to write useless tests. The frontend part is built on AngularJS and it supports unit testing perfectly, our job is just to write tests and write them right. In this article, I will share you one of our best practices to test the Angular directive and component. I will focus mainly on Angular 1 but you can apply the same idea on Angular 2 applications.

How to write… useless tests

Let’s do a remark of useless test by writing unit tests example component below. The component is used to display the basic user information and the Follow/Unfollow button to provide following feature like Twitter:

The userDisplayController:

And the content of user-display.html:

We split each component/controller/view to a single file to read, maintain easier.

Now, it’s time to write unit test. Generally, we write test for the controller because it contains almost all of logic. It’s not hard to notice that we need to test the logic of toggleFollow() function:

Done. Looks perfect, no? Yes, no.

The problem of the test cases we wrote is that they are too tightly bound to the implementation, not the functionality of the component. It leads to a situation when we want to change the implementation but keep the functionality, we have to change the test while we should not have to. Furthermore, the tests cover only small part of the component, they do not make sure that the Unfollow button appears when the user clicks on Follow button and vice versa.

Let’s write better tests

The idea of writing better tests is we test the functionality of the component, not its implementation. What is the functionality of the user-display component? It displays the basic user information and allows the current user to follow/unfollow the displayed user. Instead of seeing the component as three parts (the component declaration, the controller and the view), we see it as an unified component providing a functionality and write black-box tests for it.

Once again, Angular supports us perfectly in testing component/directive. We can compile the component, make jQuery-like calls to trigger events to simulate the user actions. We will write test cases to make sure:

  • The user information are displayed
  • The current user can click on Follow button to follow the displayed user and vice versa

Here is the result:

Conclusion

Writing unit test is good, but it will not be useful if you write test to prove the fact, the code you write. It must be used to prove the functionality you write.

The example we use in this article is quite simple so you might not feel the power of this testing method. In real life projects, we wrote some complicated directives/components where the best practice testing came and helped a lot. Check out our sub-header (code, test) and drag-and-drop (code, test) components to see it in action.

Keep in touch with us on Github, Twitter or even join our awesome team by applying to these jobs offers.

Happy unit testing!