I have a controller that performs an asynchronous operation, which I would like to test:
/*globals Ember, momnent*/
import { raw as icAjaxRaw } from 'ic-ajax';
//...
actions: {
foo: function() {
var req = icAjaxRaw({
type: 'POST',
url: ApiUtils.apiUrl+'/dofoo',
processData: false,
});
return req.then(
function resolve(result) {
console.log(result.response);
this.set('fooLastDoneAt', moment());
}.bind(this)
);
},
... and in the tests:
test('actions.foo', function() {
expect(2);
var ctrl = this.subject();
var model = {
fooLastDoneAt: moment().add(-10, 'days'),
};
ctrl.set('model', model);
ok(ctrl.get('fooLastDoneAt').isBefore(moment().add(-1, 'days')), true, 'initial');
ctrl.send('foo');
ok(ctrl.get('fooLastDoneAt').isBefore(moment().add(-1, 'days')), false, 'updated date');
});
However, this inevitably results in an error being thrown, in another, unrelated, test case:
"Uncaught Error: Assertion Failed: calling set on destroyed object"[
which must be occurring because this.set('fooLastDoneAt', moment());
is executed after this test case has finished, and the test runner has done a teardown
for this module, and gone on to the next one; while the action is still executing.
Is there a way for me to wait for an action to complete, asynchronously, before moving on to the next step the unit test?
@kingpin2k suggests this solution , where you pass in a promise deferred object into the action. However, in my app, the app itself would never do this, and it seems like a fundamental problem if I need to modify my app source just so that it can be tested - especially since it adds added complexity.
Are there any other ways to make the test execution wait for the action to complete?
I would go for QUnit
start()
stop()
functions.
Here is example of using taken from QUnit documentation:
QUnit.test( "a test", function( assert ) {
QUnit.stop();
asyncOp();
setTimeout(function() {
assert.equals( asyncOp.result, "someExpectedValue" );
QUnit.start();
}, 150 );
});
Also ember-qunit library covers this with then
.
Here is example for ember-qunit
test('actions.foo', function() {
expect(2);
var ctrl = this.subject();
var model = {
fooLastDoneAt: moment().add(-10, 'days'),
};
ctrl.set('model', model);
ok(ctrl.get('fooLastDoneAt').isBefore(moment().add(-1, 'days')), true, 'initial');
ctrl.send('foo').then(function(){
ok(ctrl.get('fooLastDoneAt').isBefore(moment().add(-1, 'days')), false, 'updated date');
});
});
I didn't test the code so I hope it solves your problem
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.