ekkis
ekkis

Reputation: 10226

Do it() calls within a describe() execute synchronously?

it has been my understanding that execution of it calls in a test suite happen sequentially i.e. that one call won't execute until the previous has completed. however, I'm seeing disagreeable behaviour where the callback for a second request is executing before the callback for a first request has completed

I don't know if my premise is wrong (as some on IRC have said, indicating that it calls are supposed to be independent of each other and can execute in parallel) or my implementation is somehow flawed

my question: if I wanted to test a conversation with a bot (where I need to await for a response from the server before issuing another request), could I do it as a series of it calls? sort of like:

describe('conversation', () => {
   it('begins chat', () => {
      fetch(server + '?hello').then(res => {
         assert.equal(res, 'EHLO');
      })
   })
   it('login request', () => {
      fetch(server + '?login=xxx').then(res => {
         assert.equal(res, 'User logged in');
      })
   })
   it('get headers', () => {
      fetch(server + '?headers').then(res => {
         assert.equal(res, '0 xxx xxxx');
      })
   })
})

or do I need to do something like:

it('conversation', async () => {
   var res = await fetch(server + '?hello')
   assert.equal(res, 'EHLO');
   res = await fetch(server + '?login=xxx')
   assert.equal(res, 'User logged in');
   res = await fetch(server + '?headers')
   assert.equal(res, '0 xxx xxxx');
})

in which case I need to substantially increase the timeout since the conversation may be long?

Upvotes: 0

Views: 87

Answers (1)

Nicholas Carey
Nicholas Carey

Reputation: 74267

fetch() is async. Your tests will always succeed as it() callback kicks off the fetch() operation and returns. At some later turn of the event loop, the fetch() operation's .then() callback is invoked and throws an exception (or not). That might or might not show up in the console long as an unhandled promise rejection.

You could use chai-with-promises. Or, even easier, use async/await:

describe('conversation', () => {

  it('begins chat', async () => {
    const res = await fetch(server + '?hello');
    assert.equal(res, 'EHLO');
  });

  it('login request', async () => {
    const res = await fetch(server + '?login=xxx')
    assert.equal(res, 'User logged in');
  })

  it('get headers', async () => {
    const await fetch(server + '?headers');
    assert.equal(res, '0 xxx xxxx');
  })

})

Do these tests have a dependency on each other? Test should be independent. If you're trying to test a protocol handshake, you might want to do something like this:

describe('conversation', () => {

  it('does the expected', async () => {
    let res;

    res = await fetch(server + '?hello')
    assert.equal(res, 'EHLO');

    res = await fetch(server + '?login=xxx') )
    assert.equal(res, 'User logged in');

    res = await fetch(server + '?headers') )
    assert.equal(res, '0 xxx xxxx');

  })

})

Upvotes: 1

Related Questions