Nock does not intercept API call in Redux test

I am trying to test api call in redux application. The code pretty much follows the pattern described in the "Action Async Creators" section of redux docs:

http://redux.js.org/docs/recipes/WritingTests.html

Its essence is that you use savex-mock-store to record and approve against any initiated actions.

This is the whole test, using nock to make fun of the api call:

import React from 'React' import ReactDOM from 'react-dom' import expect from 'expect'; import expectJSX from 'expect-jsx'; import TestUtils from 'react-addons-test-utils' import configureMockStore from 'redux-mock-store' import thunk from 'redux-thunk' import nock from 'nock' expect.extend(expectJSX); import * as types from '../../constants/Actions' describe('Async Search Actions', () => { const thunkMiddleware = [ thunk ]; /* use redux-mock-store here */ const mockStore = configureMockStore(thunkMiddleware); describe('The fetchArtistData action creator should', () => { afterEach(() => { nock.cleanAll() }) it('Should fire off a ARTIST action when fetch is done', (done) => { nock('http://ws.audioscrobbler.com') .get('/2.0/') .query({method: 'artist.search', artist: 'ho', api_key: 'abc123', format: 'json', limit: 5}) .reply(200, { fake: true } ) const expectedActions = [ { type: types.ARTIST, artists: { fake: true } } ]; let store = mockStore([], expectedActions, done); store.dispatch(fetchArtist('ho')) }); }); }); 

But it seems that when the test is executed, the real lastFm api is called ... the real data is returned from lastFm, and not a fake answer to the knock.

This is the creator of the action:

 export function fetchArtist(search) { return dispatch => { return fetch(`http://ws.audioscrobbler.com/2.0/?method=artist.search&artist=${search}&api_key=abc123&format=json&limit=5`) .then(handleErrors) .then(response => response.json()) .then(json => { dispatch(ArtistData(searchTerm, json)) }) .catch(handleServerErrors) } } 

The statement fails because the live lastFM response does not match the answer I expect according to the expectedActions object ..

I tried to assign a knock to a variable and log it. The magazine shows this:

Knock seems to add port 80 to the url, not sure if this causes the actual API not to make fun of:

  keyedInterceptors: Object{GET http://ws.audioscrobbler.com:80/2.0/? method=artist.search&artist=john&api_key=abc123&format=json&limit=5 

Any ideas what is wrong here?

+7
tdd redux nock
source share
2 answers

To use nock, you have to run your tests in node (using Jest or mocha), nock overrides the behavior of node http and for this reason only works in node, not browsers (e.g. PhantomJS).

For example, the link you pointed to uses Jest, and the first lines are explicitly specified in the node environment. Therefore, the knock will work like a charm. http://redux.js.org/docs/recipes/WritingTests.html

Customization

We recommend Jest as a testing mechanism. Note that it works in a node environment, so you won’t have access to the DOM.

As I can see, you can:

  • run tests in node environment
  • or use another library to fake fetch-mock
+3
source share

You only need to pass the base URL of the main nock function and separate the part of the URL path from the .get() method.

 nock('http://ws.audioscrobbler.com') .get('/2.0/') .query({ method: 'artist.search', artist: 'bob', api_key: 'somekey123', format: 'json', limit: '5' }) .reply(200, {fake: true}) 

I managed to get a fake answer with the above code.

0
source share

All Articles