admin管理员组

文章数量:1201403

I am working with a Jasmine testing suite that includes both "vanilla" Jasmine tests along with Jasmine tests for some Angular 2 components. Because of Angular 2's inclusion, zone.js gets loaded. This creates a conflict with Jasmine's clock. For example, the following test fails with the error, Error: Jasmine Clock was unable to install over custom global timer functions. Is the clock already installed?

describe('an async test with zone.js present', function() {
  beforeEach(function() {
    jasmine.clock().install();
  });

  afterEach(function() {
    jasmine.clock().uninstall();
  });

  it('cannot install jasmine\'s mock clock', function() {
    var callback = jasmine.createSpy('setTimeoutCallback')
    setTimeout(callback, 55);
    jasmine.clock().tick(56);
    expect(callback).toHaveBeenCalled();
  });
})

Here is plunker for above code.

Short of delivering the Angular 2 tests separately from the "vanilla" tests, I am wondering what options might be available. For example, is it possible to perform the Jasmine clock's job with the zone? For example, is it possible to simulate the tick with the zone or flush all of the scheduled tasks before the assertion?

I am working with a Jasmine testing suite that includes both "vanilla" Jasmine tests along with Jasmine tests for some Angular 2 components. Because of Angular 2's inclusion, zone.js gets loaded. This creates a conflict with Jasmine's clock. For example, the following test fails with the error, Error: Jasmine Clock was unable to install over custom global timer functions. Is the clock already installed?

describe('an async test with zone.js present', function() {
  beforeEach(function() {
    jasmine.clock().install();
  });

  afterEach(function() {
    jasmine.clock().uninstall();
  });

  it('cannot install jasmine\'s mock clock', function() {
    var callback = jasmine.createSpy('setTimeoutCallback')
    setTimeout(callback, 55);
    jasmine.clock().tick(56);
    expect(callback).toHaveBeenCalled();
  });
})

Here is plunker for above code.

Short of delivering the Angular 2 tests separately from the "vanilla" tests, I am wondering what options might be available. For example, is it possible to perform the Jasmine clock's job with the zone? For example, is it possible to simulate the tick with the zone or flush all of the scheduled tasks before the assertion?

Share Improve this question edited Oct 20, 2016 at 15:03 lewistg asked Sep 20, 2016 at 18:00 lewistglewistg 3384 silver badges9 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 6

For me it works if you uninstall the clock in beforeEach. Its not recommended by jasmine and a bit strange because for uninstall it makes more sense to use afterEach. But calling uninstall before the first install call happens fixed it for me.

As stated on Angular documentation you should use tick function in a fakeAsync body which is part of the @angular/core/testing module.

Using your example and TypeScript it would look something like this...

import { fakeAsync, tick } from '@angular/core/testing';

...

it('cannot install jasmine\'s mock clock', fakeAsync(() => {
   var callback = jasmine.createSpy('setTimeoutCallback')
   setTimeout(callback, 55);
   tick(56);
   expect(callback).toHaveBeenCalled();
}));

The code which throws this here.

It implies that jasmine was loaded before Zone.js. Switch the loading order. Zone always needs to be loaded first.

Here's the fixed fork of your plunker:

<script data-require="zone.js@*" data-semver="0.4.1" src="https://cdn.rawgit.com/angular/zone.js/v0.4.1/zone.js"></script>
<script data-require="zone.js@*" data-semver="0.4.1" src="https://cdn.rawgit.com/angular/zone.js/v0.4.1/long-stack-trace-zone.js"></script>
<script data-require="jasmine@*" data-semver="2.4.1" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/boot.js"></script>

https://plnkr.co/edit/6iuvWFOZLqHWJIo4

This have been resolved by https://github.com/angular/zone.js/pull/1009. zone.js and future angular will support jasmine.clock().

本文标签: javascriptConflict between zonejs and Jasmine39s clockStack Overflow