Using jasmine.clock() with async/await

747 views
Skip to first unread message

Michael Giambalvo

unread,
Aug 23, 2016, 11:47:27 AM8/23/16
to Jasmine
I ran into an issue the other day trying to use jasmine.clock() in my test suite. My project uses TypeScript 1.8,  compiles to ES6, and runs on Node 6.4.  It's possible I'm just doing something totally wrong, so bear with me.

I have a helper function that returns a promise, like so

simulateSendingMessage(text: string) {
   // Do some stuff
   return new Promise((resolve) => {
      setTimeout(() => {
         resolve();
         sendMessage();
       }, 500);
   });
}

Then, in my test, I have

it('should wait half a second', async (done) => {
  jasmine.clock().install(); 
  jasmine.clock().tick(600);
  await simluateSendingMessage();
  expect(messageSent).toBe(true);
  jamsine.clock().uninstall();
  done();
});

The problem as I see it is that the Jasmine clock replaces setTimeout with a mock. The callback passed to the mock setTimeout isn't called until jasmine.clock().tick() is called. However, I don't get past the 'await' line until the promise resolves. If I don't use Jasmine's clock, the test runs as expected. I can also use jasmine's clock, I just have to handle promises manually instead of using async/await, like this.

it('should wait half a second', (done) => {
  jasmine.clock().install(); 
  let messagePromise = simluateSendingMessage();
  jasmine.clock().tick(600);
  messagePromise.then(() => {
    expect(messageSent).toBe(true);
    jamsine.clock().uninstall();
    done();
  });
});

The key is that I'm able to call tick after the promise is created, but before I wait for it to resolve. 

I realize I'm kind of on the bleeding edge here, but I was wondering if anyone had run into this before? Am I doing things right and this is just the expected behavior currently, or is there a better way to do what I'm trying to do. I really like being able to use async/await, but I need to be able to use the mock clock for my tests.

Thanks!

Thomas Achleitner

unread,
Sep 1, 2016, 5:15:50 PM9/1/16
to Jasmine
We had the same problem and decided to write a wrapper around setTimeout to be able to inject and therefore mock the functionality.
 
import { injectable } from 'inversify';

import { ITimeoutService } from './ITimeoutService';

/**
 * @implements {ITimeoutService}
 */
@injectable()
export class TimeoutService implements ITimeoutService {

  /** @inheritDoc */
  public wait(timeInMs: number): Promise<void> {
    return new Promise<void>((resolve) => {
      setTimeout(resolve, timeInMs);
    });
  }
}
Reply all
Reply to author
Forward
0 new messages