I am using Sinon with Ember.js Concurrency Tasks and am trying to stub the task in a test.
The code looks something like this:
component .ts file:
import Component from '@glimmer/component';
import { TaskGenerator, TaskInstance } from 'ember-concurrency';
import { task } from 'ember-concurrency-decorators';
import { taskFor } from 'ember-concurrency-ts';
export default class Container extends Component<Args> {
@task *myTask(): TaskGenerator<Data> {
const response: Data = yield json('someURL'); //json() returns a JSON object from a request to someURL
return response;
}
get task(): TaskInstance<Data> | null {
const task = taskFor(this.myTask);
return task.last ? task.last : task.perform();
}
@action
someMethod(): void {
const task = taskFor(this.myTask);
task.perform();
}
}
relevant test from component test file:
...
module('Integration | Component | container', function(hooks){
test('some test', async function(this: Context, assert) {
await render(hbs`
<Container @someMethod={{@someArgument}} as |c| >
// some code that uses c
</Container>
`);
}
How would I stub the myTask task? I would essentially like to have it so that I am able to manually control the response that comes out of myTask so an HTTP response doesn't have to be made in the test.
I'm not aware of any way to mock a single task in a component for testing. When the network is involved I reach for ember-cli-mirage which is built on pretender. Mirage is very good when working with ember-data models and can also be used to handle mocking any network request. If you're not using ember-data you may want to just use pretender or investigate the non-framework Mirage.js.
By mocking the network and returning canned data you will have the same control over your tests while testing the component as is. I really like this approach and have found it to be very reliable and stable for several years.