jameslnewell/xhr-mock

Throws 'A handler errored' to console after upgrading to 2.3.0

henri-hulski opened this issue ยท 11 comments

After upgrading to version 2.3.0 I get some of the following errors when running my tests:

   console.error node_modules/xhr-mock/lib/MockXMLHttpRequest.js:673
      xhr-mock: A handler errored:
       Error: xhr-mock: No handler returned a response.
          at /home/pacha/web/cerebral/auth-boilerplate/node_modules/xhr-mock/lib/handle.js:31:19
          at <anonymous>

But the tests are still passing.
One example test which throws to console:

import mock from 'xhr-mock'
import { CerebralTest } from 'cerebral/test'

import app from '.'

beforeEach(() => {
  mock.setup()
  localStorage.removeItem('jwtHeader')
})

test('should refresh token when expired token and refresh allowed', async () => {
  expect.assertions(2)

  localStorage.setItem(
    'jwtHeader',
    JSON.stringify(authHeader.expiredRefreshableJwt)
  )
  let cerebral = CerebralTest(app({ flash: null, flashType: null }))

  mock.get('/api/refresh', (req, res) => {
    return res
      .status(200)
      .header('Content-Type', 'application/json')
      .header('Authorization', authHeader.validJwt)
  })

  await cerebral
    .runSignal('appMounted')
    .then(({ state }) => [
      expect(state.user.authenticated).toBe(true),
      expect(state.user.nickname).toBe('Tester'),
    ])
})

I do not really understand why it throws this error.

Hi @henri-hulski. Thanks for reaching out. The error isn't being thrown, its being logged. Prior to v2.3 there was no reporting of errors that occurred in handlers or due to a lack of matching handlers for the requested URL. This made it very difficult to debug whether the error event emitted by the xhr was real, was due to xhr-mock or was due to a handler. This behaviour masked real problems within tests.

v2.3 changes this behaviour by logging the errors by default. If you wish, you can change how errors are logged by setting mock.error(({req, err}) => {/* log the error, or don't log the error as you please */}). However, with the default behaviour, the only times you should actually see errors logged is when your handler looks like this (req, res) => Promise.reject(res). All other errors logged will uncover real problems with your tests. For example, in the reported example you'll want to look into why your mock.get() isn't being matched.

@jameslnewell thanks for your answer.
I actually found out that the error mean that a url which was called was not covered by a mock.
Really great for debugging the tests.

Is there an option to print out the url which is not covered? Normally it's not a problem, but in the above case I was not able yet to find out, which url is called.

Yep sure. You have access to the request in the error callback.

eg:

mock.error(({req, err}) => console.log(req.url(), err)

I'll look at including the request details in the message by default.

@jameslnewell Hmm It's quite strange.
When adding

mock.error(({req, err}) => console.log(req, err))

I get

PASS  client/app/app.test.js (5.261s)
  โ— Console

    console.log client/app/app.test.js:11
      MockRequest {
        _method: 'GET',
        _url: MockURLImplementation { path: '/api/refresh', query: {} },
        _headers:
         { 'content-type': 'application/json; charset=UTF-8',
           accept: 'application/json',
           authorization: '' },
        _body: null } Error: xhr-mock: No handler returned a response.
          at /home/pacha/web/cerebral/auth-boilerplate/node_modules/xhr-mock/lib/handle.js:31:19
          at <anonymous>

Which is not expected as I actually have a handler for this case as you can see above.
When removing the handler I get 2 times the same message and the test is failing.

Ok I have solved it. My bad!
Had just to move mock.get before CerebralTest().

Really much better for debugging now.
Found some important issues!

๐Ÿ•บ

In v2.3.1 I've updated the default error logging to look like this:

      xhr-mock: No handler returned a response for the request.

        GET / HTTP/1.1

      xhr-mock: A handler returned an error for the request.

        GET / HTTP/1.1

        Error: ๐Ÿ˜ต
            at /Users/jnewell/code/xhr-mock/packages/xhr-mock/test/acceptance.test.ts:277:41
            at /Users/jnewell/code/xhr-mock/packages/xhr-mock/src/createMockFunction.ts:55:16
            at /Users/jnewell/code/xhr-mock/packages/xhr-mock/src/handle.ts:42:20
            at <anonymous>

Feel free to suggest better messages/formatting. Ty.

Cool! I think it would make sense to include some request info at least in the first case.
Really helps debugging.

XHR-mock v.2.3.1 fixed also another problem.
In another app I suddenly had a handful of failing tests after upgrading to 2.3.0.
Seems that xhr-mocks has overridden the HttpProviderError which is thrown by @cerebral/http but which is actually part of the workflow.
With 2.3.1 this is fixed.

I've never used cerebral but the other fix in v2.3.1 was #58.