How to test an Angular app using Karma and Jasmine

Sebastian Ravenscroft
3 min readJun 3, 2021

--

For this guide we will start with a fresh install of Angular 12.

You can use NPM to install the Angular CLI:

npm install -g @angular/cli

Now create a new Angular app:

ng new myapp

cd myapp

Angular installs with Karma and Jasmine test runners ready to go!

(Take a look at the angular.json file and you will see a “test” object where Karma is wired up).

You can easily run your tests from the Angular CLI:

ng test

A browser window opens up and Karma quickly runs through your tests. It runs through each test by simulating a user clicking through your app.

You’ll also see the test results output in your terminal window looking something like this.

In your code editor open up src/app/app.component.spec.ts and you will see the code for the 3 tests that just ran:

These tests are written using some methods provided by Jasmine. Luckily the syntax is simple!

We use the describe() wrapper to group our tests and provide a description for the test output. In this case the description is simply ‘AppComponent’.

Now we have a beforeEach() method which takes a callback. As we are testing a whole Angular component we need to simulate the app environment where it would usually run. We use the TestBed provided by Angular testing module to mock the component’s dependencies.

Then we use the it() method used to run a test. It takes a description (or expectation) and a callback function defining the steps to run the test.

Finally the expect() method lets us make assertions for the results of our test.

Writing our first test

Add a new test to the app.component.spec.ts file:

We use the querySelector to find the HTML element with class .content and check that the first <h1> heading reads ‘App Users’.

When you run this test it will fail. Fixing it is easy, just add the heading to the src/app/app.component.html file.

<h1>App Users</h1>

How to mock API calls

Your app probably loads data from an API and we don’t want to call the API for every single test. We need to mock the API call in order to return an example response, and then test that our component handles that response correctly.

In the project root create a new src/respositories/UserRepository.ts file.

Also create a src/testing/UserRepositoryMock.ts file. Here we return a hard coded user (Jane Doe) which we will use for testing.

Finally update your app.component.spec.ts file to pull in the UserRepositoryMock class via the providers: [] array.

Test the component using mock data

We want write a test to check that, given some mock user data, our component will render those users in a table.

Start by replacing the contents of app.component.html with a table where we will list the users returned by the API.

As we removed the initial holding page we also need to remove the related test from app.component.spec.ts. Delete the test called it(‘should render title’…).

Also update app.component.ts controller in order to fetch the user records from the UserRepository.

Now we can add our new test to the end of app.component.spec.ts

We need to wrap the contents of our test in a fakeAsync() call which lets us wait for promises to resolve.

Before we can make assertions against the page contents we need to allow the component to initialise, fetch the mock data, and update the view.

Calling tick(1) advances the virtual timer by 1 millisecond, then we need to call detectChanges() in order to let the component re-render.

Run the updated test suite and you should see all the tests pass:

ng test

This is great progress. We now have a way to mock our APIs and test that our components render data correctly!

--

--

Sebastian Ravenscroft
Sebastian Ravenscroft

No responses yet