Ember testing: You have turned on testing mode, wh

2019-06-19 01:51发布

问题:

I am trying to write a simple Ember integration test and continue to get the frustrating run loop error despite using Ember.run. I've had a nightmare of a time trying to get this to work, if anyone could help me I'd be so grateful. Specifically, I can see the test sign in and begin loading the next page (as it should), but as soon as the test finishes I get that error. This is regarding the second test, the first passes (as nothing is async I believe).

import Ember from 'ember';
import startApp from 'jobs-tuftsdaily/tests/helpers/start-app';
import exists from 'jobs-tuftsdaily/tests/helpers/start-app';

var App;

module('Integration - Landing Page', {
    setup: function() {
        App = startApp();
    },
    teardown: function() {
       Ember.run(App, 'destroy');
    }
});

test('Should load content', function() {
  visit('/').then(function() {
    ok(exists("*"), "Found HTML!");
    ok(exists('label:eq(4)'), "Slug label on page");
  });
});

test('Should sign in test user', function() {
  Ember.run(function() {
    visit('/').andThen(function() {
      return fillIn("input[name=email]", "test@test.com");
    }).andThen(function() {
      return fillIn("input[type=password]", "password");
    }).andThen(function() {
      return click("button");
    }).andThen(function() {
      ok(1, "stupid test passed");
    });
  });
});

回答1:

I realize I am late to the party, but here goes anyway:

Somewhere in your component or application code (that is, NOT in the test code), you probably listen to some event outside of Ember (e.g. a DOM event, through jQuery, or something like that), but try to interact with it during that handler's run. These handler functions must be wrapped in Ember.run.bind(), or they won't have a runloop during a test. Ember.run.bind() will also set this for you during the handler.

If you don't wrap your event callbacks in Ember.run.bind(), the code will probably still run without hassle during a normal run of the application because the autorun feature will find runloop-demanding (for example, if you schedule something using Ember.run.schedule() during the handler) interactions with Ember in the code and start a runloop for them, but it's turned off in tests.



回答2:

I got the same issue in a component's integration test. The error is:

Assertion Failed: You have turned on testing mode, which disabled the run-loop's autorun.

You will need to wrap any code with asynchronous side-effects in a run.

And I found the reason of problem for integration tests. I'm rendering the component with the following code:

let myobject = Ember.Object.create({x:1});
this.set('param', myobject)
this.render(hbs`{{my-object param=param}}`); 

After rendering, updating myobject as below is causing the error.:

myobject.set('x',2);

Because it is not inside of an ember run-loop.

Instead of this erronous calling, updating the value should be done as one of the followings:

this.set('param.x',2); 
//OR:
this.set('param', Ember.Object.create({x:1}); 
//OR:
Ember.run(()=>{
    Ember.set(myobject,'x',2);
});

For your case: I didn't try but my opinion is that async test helpers such as visit, click, fillIn can be used in acceptance tests not in integration tests because of the following reason.



回答3:

Wrapping your tests in Ember.run won't help as the error you are getting is not happening because the test code but the code of your application. In your sign in route you must be doing some asynchronous requests (like AJAX or setTimeout even) and in their handlers you perform some Ember API executions (like setting, transitioning, anything).

If you would like any exact help about that you need to post your code in the route/controller.

I recently published an ebook about the Run Loop, including the autorun mechanism that can be downloaded here.