Generate Angular Unit Test Automatically

How much do you like to write unit tests from the scratch? My guess is “not so much”. The reason behind this guess is that writing the first successful unit test is just a copy/paste/modification job, and it’s not a pleasant task.

What if there is a command that can do this job(copy/paste/modification)?

TL;DR; Yes, there is a command.

Assuming you coded your component, and you want to write a test,

$ npm install ngentest -g # to run this command anywhere
$ ngentest my.component.ts # node_modules/.bin/gentest

This will output your auto-generated unit test, and it’s guaranteed to work.

Test requires more coding, and it’s true :(

Writing a component is one thing and testing it is another thing. To make your test to work, you need to know and code more the following;

  • Import statements
  • Classes to mock
  • Window objects to mock
  • Create TestBed and configure it before each tests
  • Setup providers using mocks
  • Etc

The above is just for a component. When it comes to a directive it requires even more for you to code;

  • Create a component to test a directive
  • Get the directive instance from the component
  • Setting up @inputs and @outputs to test
  • and more

It already makes you tired before you write the test. You have been doing this job by copying, pasting and modifying your code, and I am sure you don’t like it. If there were an AI program, then I would ask AI program to do this job rather than I write it by myself.

Generate the first unit test automatically

There is no reason to automate copying/pasting/modifying the test codes for each type; components, directives, services and pipes. It’s just a matter of;

  1. Parsing a Typescript file and find out the proper file type.
  2. Building data for unit test from the parsed Typescript.
  • className
  • imports
  • input/output attributes and properties
  • mocks
  • providers for TestBed
  • list of functions to test

3. Finally, generating unit test from a template

That’s how the Angular Test Generator has been created. https://github.com/allenhwkim/ngentest.

By running a ngentest command, more than half of your test will be done. The only thing you have left is to complete each function tests.

$ ngentest my.component.ts # node_modules/.bin/gentest
$ ngentest my.directive.ts -s # output to my.directive.spec.ts
$ ngentest my.pipe.ts > my.pipe.test.ts
$ ngentest my.service.ts

As you see it here from the generated code example, the constructor test is complete, but function tests for the class is not done, and I don’t think even an AI can do this properly(one day, maybe?). You still need to complete each function tests to make the code coverage 100%.

  it('should create a component', async(() => {
expect(component).toBeTruthy();
}));

it('should run #ngOnInit()', async(() => {
// ngOnInit();
}));

it('should run #handleIntersect()', async(() => {
// handleIntersect(entries, observer);
}));

it('should run #defaultInviewHandler()', async(() => {
// const result = defaultInviewHandler(entry);
}));

Sorry, it does not fully generate ALL of your unit test. The good thing is it generate more than half of your unit test. However, even with this small help, you can save a lot of time. These are number of lines generated for unit tests for each type for me.

  • 89 out of 137 lines for my component
  • 90 out of 139 lines for my directive
  • 25 out of 43 lines for my service
  • 12 out of 20 lines for my pipe

In general, with ngentest, you can write more than half of your unit test.

Conclusion

You can find the code here at Github, https://github.com/allenhwkim/ngentest

To try this, all you need to do is to install and run ngentest with your file.

$ npm install ngentest -g # to run this command anywhere
$ ngentest my.component.ts

Happy Coding :)

May 12th, 2018

Allen Kim

Do you think this useful? If so please;
*
Clap 👏 button below️ to let others to see this too.
* Follow Allen on Twitter (@allenhwkim)!