简体   繁体   中英

Introduce momentary delays in ember-cli-mirage

I am using ember-cli-mirage for acceptance tests. For a specific case, I would like to check the behaviour while fetching data over a slow connection.

There's a setting in ember-cli-mirage called timing that simulates a delay in the response. However, this setting cannot be changed to be different in a specific test:

// app/mirage/config.js
this.timing = 400;

Something else I have tried is returning a promise at the fake endpoint. Through some import/export, I could control the resolution of the promise from my test. Unfortunately, ember-cli-mirage doesn't seem to recognise the return value as a promise, and simply passes it back to the adapter verbatim:

// app/mirage/config.js
this.get('/StopPoint/Search/:term', (db, request) => {
  return freezer.run(function() {
    return db[`stop-point-search-${request.params.term}`][0];
  });
});

// At my test
freezer.on()
runTests()
freezer.off()

The question : is there any way to do this? Ie: to control the delay of a specific response in ember-cli-mirage?

A few thoughts:

  • You can change timing within a specific test via server.timing . The server should be reinstantiated for each test so this wouldn't affect other tests.

     test('for slow behavior', function() { server.timing = 400; // });
  • You can also redefine route handlers within tests as shown here in the second example of the Acceptance testing guides . If you're using 0.2.0-beta , route handlers have a timing option you can use to affect just that handler:

     test('for slow behavior', function() { server.get('/slow-query', (schema, request) => { // return data; }, {timing: 400}; visit('/'); // assert(); });

I think your instinct to return something you have control over freezing would be the ideal way to test this, in tandem with something like Timecop . Perhaps Mirage can add an API for this eventually.

We had to test that our <progress> element displays in a test using mirage and discovered that making the render method syncronous and piggybacking off of waitFor and settled works best (and doesn't require setting this.server.timing at all):

const SELECTORS = {
    LOADING_SPINNER: '[role="progressbar"]'
};

test('it displays loading spinner when fetching blog post', async function(assert) {
    this.blogId = 1;
    render(hbs`<BlogPost @blogId={{this.blogId}}/>`); // NOTE: no await
    await waitFor(SELECTORS.LOADING_SPINNER);
    assert.dom(SELECTORS.LOADING_SPINNER).exists({ count: 1 }, 'loading spinner rendered while blog post loads');
    await settled();
    assert.dom(SELECTORS.LOADING_SPINNER).doesNotExist('loading spinner removed when blog post loaded');
});

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM