loading...

Angular Unit Test Automation

gparlakov profile image Georgi Parlakov Originally published at itnext.io on ・4 min read

How can I automate my unit test creation and update chores?

What if I told you that I can auto-generate your unit tests? And then maintain them?

TL;DR;

No chores. No boring boilerplate. Just tests.

Install SCuri and create or update a spec file by:

**npm install scuri**
 **ng g scuri:spec --name src/app/my.component.ts** 
_# OR to update an existing spec_
**ng g scuri:spec --name src/app/with-spec.component.ts --update**

This requires Angular CLI 6. For previous versions see troubleshooting section in the readme.

Screencast of using the SCuri tool on the command line
Caption actually uses the schematics CLI which supports Angular < 6

Wow, this looks great. But what’s the catch?

There is actually just one:

  1. Structure your tests in a specific fashion.*

*or rather keep it as the tool generates them

SCuri assumes that the tests will have a specific structure. It assumes there is a setup function (or creates one if it’s missing) where the setting up of the spec conditions occurs. And that the names of the tests include the names of public methods on the class-under-test. Read more about it in this article (see point 4 and on).

These assumptions allow it (SCuri) to automate the tasks of creation and update of unit tests for Angular components, services, and plain old typescript classes.

But wait, ng c component already generates a spec, right? Why do I need another tool?

Yes, it does. But as soon as the first dependency is added to that generated component and the test needs to be updated , that’s where Angular CLI falls short. And that’s where SCuri shines!

Let’s try it!

Assuming SCuri is installed npm install scuri in the project folder and the Angular CLI is version 6 or greater.

I’ve created a demo component with no tests

ng g demo --skipTests

ng g scuri:spec --name src/app/demo/demo.component.ts

There are a couple of things to note here:

  1. The setup function. This is where all the setting up of tests preconditions and dependencies would occur.
  2. The autoSpy function. This is what will create automatic mocks for your dependencies. It will take any class and mock its public methods (s_ee details in_ SCuri readme). And it can be generated for you by the tool! ng g scuri:autospy — for jasmine:

Now for the fun part:

Create a service:

ng g service my

Include it it the component dependencies. Let’s also add a public event handler method for good measure.

Now run ng g scuri:spec --name src/app/demo/demo.component.ts --update

And now the dependency is mocked , included in the MyComponent build function! And the new method has a test scaffolded for it!

All that’s left is the logic, that only you , the human being, can author.

What else can I use the setup function for?

For each test case, we usually require some setup. And leaving that in the it body makes it difficult to read. So we can use the builder that setup returns and attach methods on it for setting up the specific details.

For example, let’s say that we need to fetch some data in ngOnInit

We run ng g scuri:spec --name src/app/demo/demo.component.ts --update again to update dependencies. And now we can use the mock created by autoSpy in the test:

Or we can move the mock part in the setup builder:

Now our test is cleaner and calls a method that is named so as to speak to the reader what the goal is, rather than expect them to read through the mock declaration and extrapolate what the author meant. The name carries the author’s intent! (this is a contrived and trivial example — think of what your components do and how you mock that!)

Notice how we call the withHeroes in the default builder method. That’s because every time we call ngOnInit we’ll need an observable to subscribe to, otherwise our we’ll get an exception that there is no subscribe method on undefined

Let’s put SCuri to the test! (:

Let’s try it on a real-world project! What better than The Real World Example App! It’s an example Medium clone Angular app, that just so happens has no unit tests (as of today).

git clone [https://github.com/gothinkster/angular-realworld-example-app](https://github.com/gothinkster/angular-realworld-example-app)
cd angular-realworld-example-app
npm install scuri
ng g scuri:spec --name src/app/home/home.component.ts

And now the src/app/home/home.component.spec.ts has the dependencies mocked and ready, and the public method tests scaffolded. All ready for you to do the tests magick.

No chores. No boring boilerplate. Just tests.


Posted on by:

gparlakov profile

Georgi Parlakov

@gparlakov

Angular and DotNet dev. RxJs explorer. Testing proponent. A dad. https://gparlakov.github.io/

Discussion

pic
Editor guide