Angular Unit Test Automation
Tags: jest, testing, angular2, angular
Published: 2019-10-15 11:13:41

---
title: Angular Unit Test Automation
published: true
date: 2019-10-15 06:59:56 UTC
tags: jest,testing,angular2,angular
canonical_url: https://itnext.io/angular-unit-test-automation-8f6efcb1f1b6
---

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**](https://github.com/angular/angular-cli/releases/tag/v6.0.0). For previous versions see [troubleshooting section in the readme](https://github.com/gparlakov/scuri#rule-result-function).

![Screencast of using the SCuri tool on the command line](https://cdn-images-1.medium.com/max/960/0*dAWU-QVKc5zSyBR_.gif)<figcaption>Caption actually uses the <a href="https://www.npmjs.com/package/@angular-devkit/schematics-cli">schematics CLI</a> which supports Angular &lt; 6</figcaption>

### 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](https://dev.to/gparlakov/an-opinionated-approach-to-testing-angular-492f)).

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._

![](https://cdn-images-1.medium.com/max/917/1*chBXG2HVQT5Lcpr67oPv3w.png)<figcaption>I’ve created a demo component with no tests</figcaption>

ng g demo --skipTests

{% gist https://gist.github.com/gparlakov/52a0a7bfcc8f01509a3039035768e8df %}

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

![](https://cdn-images-1.medium.com/max/1024/1*8UqIH5jf0Ftxei3IZuhz9A.png)

{% gist https://gist.github.com/gparlakov/c7f57e00ca5f7575cf1b8340e89c5624 %}

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_](https://github.com/gparlakov/scuri#autospy-path-in-tsconfigjson)). And it can be **generated** for you by the tool!   
ng g scuri:autospy — for jasmine:

![](https://cdn-images-1.medium.com/max/893/1*A_lUzyRjzhJ2wV_bDTE1gg.png)

Now for the fun part:

Create a service:

ng g service my

![](https://cdn-images-1.medium.com/max/656/1*5LBTamsm5sVGQIsiNgI3pQ.png)

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

{% gist https://gist.github.com/gparlakov/9e1ca1a313b08720de373e4b63228c1f %}

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

![](https://cdn-images-1.medium.com/max/1024/1*zWcLuIqE_HuPvikHnOm7XA.png)

{% gist https://gist.github.com/gparlakov/9b8421b72090e182c6728853d26c42c2 %}

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

{% gist https://gist.github.com/gparlakov/a5620007768ad86cd9ecbe75051cab65 %}

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:

{% gist https://gist.github.com/gparlakov/431817dda4bfe1affb2ef18e48c9ab83 %}

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

{% gist https://gist.github.com/gparlakov/ac693f88c1f521b7e2919ceaf7786bf2 %}

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](https://github.com/gothinkster/angular-realworld-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.

* * *