fbpx

Testing exceptions with Async Await

Normally when testing your code throwing exceptions is goes something like this: (examples in typescript with Jasmine)


function isTwo(num: number): number {
  if(num != 2) throw new Error("Yo! It's not number 2!!");
  return num;
}

// ... inside describe block
it("should throw an error", () => {
  const throwError = function() { isTwo(3) };

  expect(throwError).toThrowError("Yo! It's not number2!!")
}

We wrap our function in an anonymous function and pass it to the expectation.  All is good and we move on with our day!

But what if our function is returning a promise! Aha, things can’t work the same.

Let’s use async / await to help us.


function isTwo(num: number): Promise<number> {
  new Promise(resolve, reject) {
    if(num != 2) reject("Yo! It's not number 2!!");
    resolve(num);
  }
}

// ... inside describe block
it("should throw an error", async () => {
  try {
    const throwError = isTwo(3); 
  } catch(error) {
    expect(error.message).toBe(""Yo! It's not number 2!!");
  }
}

Testing time based activities in Angular

When testing time streams or promised based activities use ‘fakeAsync’ and ‘tick’.

For example, given a service:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';

@Injectable()
export class CountdownService {
  // counts down from given number to zero
  source(num: number): Observable<number> {
    return Observable.timer(1000, 1000)
    .map( (v) => num - v)
    .takeWhile( (v) => v !== -1);
  }
}

To test the CountDown class source method:

// … test setup above, inside describe function

it('should count down from 5 to 0', inject([CountdownService], fakeAsync( (service: CountdownService) => {
    let num: number = undefined;
    const count = service.source(5).subscribe( (value) => num = value);
    tick(7000)

    expect(num).toEqual(0);
})));

Wrap the ‘it’ callback function in fakeAsync() which creates a new zone for the asynchronous code to run.

Calling tick() with a time span in ms, simulates the code after that amount of time has passed.

Use tick() with no arguments for promise based code

My expectation is based on what happens after 7 seconds has passed.