My previous post showed how to set up a component’s controller for unit testing using the $componentController
service.
We also learned that Angular doesn’t trigger the different lifecycle hooks by itself, meaning that you need to manually call $onInit
, etc.
In this post I’ll show an example for testing a component that makes use of the $onChanges
hook.
Take a look at this simple word-counting component’s $onChanges
hook:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
As you can see, the hook uses the changes
object in order to know when the text has changes, detect the initial change, and also use the previousValue
to calculate the word difference (yes, I know we could use the old words
value, but this is just for the example).
You can see the component live here.
Now, testing this component is relatively trivial.
We simply need to pass it some different values for text
, trigger $onChanges
, and that’s it.
But, the fact is that Angular, for some reason, doesn’t expose the changes object it uses internally.
That means that you’ll have to implement your own object that conforms to the changes
object protocol–each changed property needs an isFirstChange
method and 2 properties, currentValue
and previousValue
.
Since that’s a PITA, I’ve open sourced a tiny helper just for that, angular-stub-changes.
Using it, our tests now look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
|
Basically, note that we make sure to call $onChanges
with a properly configured changes object.
Also, you still have to set the updated properties on your controller instance yourself, e.g. ctrl.text = '...'
.
The creation of the stub changes object is, I hope, straightforward.
It’s a builder pattern, so you can keep on adding how many changes (.addChange(..).addChange(..)
) as needed for your component
That’s about it, happy testing!
“Maintaining AngularJS feels like Cobol 🤷…”
You want to do AngularJS the right way.
Yet every blog post you see makes it look like your codebase is obsolete.
Components? Lifecycle hooks? Controllers are dead?
It would be great to work on a modern codebase again, but who has weeks for a rewrite?
Well, you can get your app back in shape, without pushing back all your deadlines!
Imagine, upgrading smoothly along your regular tasks, no longer deep in legacy.
Subscribe and get my free email course with steps for upgrading your AngularJS app to the latest 1.6 safely and without a rewrite.