ember.jssinonember-testing

How to use sinon.useFakeTimers with ember-testing (acceptance)?


I've been successful writing unit level tests in ember w/ help from the sinon clock but acceptance tests always seem to be an issue.

For example, in my route I intend to wait 5 seconds before I do something

export default Ember.Route.extend({
    model: function() {
        setTimeout(Ember.run.bind(this, function() {
            //after the timeout do something like transition to another route
        }), 5000);
    }
});

In ember testing I'd do a simple visit, assert the currentURL() is good, then do a clock.tick(5001) w/ sinon ... then assert the timer is complete and some state was set/etc.

I realize sinon and the ember run loop don't seem to play nice together but I'm curious what other people are using to test timers like this at the high level (non unit tests /without selenium or sleep hacks).

If run later is required how would you rework the (incorrect) test below to work with clock.tick ?

test("sinon and ember play nice", function(assert) {
    var clock = sinon.useFakeTimers();
    visit("/");
    andThen(function() {
        assert.equal(currentURL(), "/");
    });
    clock.tick(5001);
    andThen(function() {
        assert.equal(currentURL(), "/the-transition-url");
    });
});

Solution

  • I think in all cases sinon.useFakeTimers() is breaking the async and sync helpers (in this case the andThen()).

    I've tested with something more like this in a similar situation:

    test("sinon and ember play nice", function(assert) {
      const clock = sinon.useFakeTimers();
      visit('/');
      clock.tick(0); // this for simulating rendering right now
      assert.equal(currentURL(), '/');
      clock.tick(5100);
      assert.equal(currentURL(), '/the-transition-url');
      clock.restore();
    });
    

    p.s.: after a lot of testing of the async helpers, looks like the async implementation on the ember-testing framework is based on the time to pass. As a side effect, no andThen() is executed until clock.tick(0); or clock.tick(50);.

    p.s.2: looks like there's another question on stackoverflow related Is there a way to run Ember.Testing acceptance tests with fake timers? and also with latest ember (2.9 and 2.10), and an upgrade of qunit, the current code needs more tweaking