问题
We have a lot of code in our project that isn't covered because of ember concurrency tasks.
Is there a straightforward way of unit testing an controller that contains something like the following:
export default Controller.extend({
updateProject: task(function* () {
this.model.project.set('title', this.newTitle);
try {
yield this.model.project.save();
this.growl.success('success');
} catch (error) {
this.growl.alert(error.message);
}
})
});```
回答1:
You can unit test a task like that by calling someTask.perform()
. For the given task you can stub what you need to in order to test it thoroughly:
test('update project task sets the project title and calls save', function(assert) {
const model = {
project: {
set: this.spy(),
save: this.spy()
}
};
const growl = {
success: this.spy()
};
// using new syntax
const controller = this.owner.factoryFor('controller:someController').create({ model, growl, newTitle: 'someTitle' });
controller.updateProject.perform();
assert.ok(model.project.set.calledWith('someTitle'), 'set project title');
assert.ok(growl.success.calledWith('success'), 'called growl.success()');
});
This is using spies from sinon and ember-sinon-qunit to access sinon from a test context, but these are not necessary for unit testing. You could stub the model and services, etc. with assertions instead of spies:
const model = {
project: {
set: (title) => {
assert.equal(title, 'someTitle', 'set project title');
},
save: () => {
assert.ok(1, 'saved project');
}
}
};
To test the catch you can throw from your stubbed model.project.save()
method:
const model = {
project: {
...
save: () => throw new Error("go to catch!")
}
};
来源:https://stackoverflow.com/questions/58452244/unit-testing-ember-concurrency-tasks-and-yields