Nock没有在Redux测试中拦截API调用 [英] Nock is not intercepting API call in Redux test

查看:85
本文介绍了Nock没有在Redux测试中拦截API调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Redux应用程序中测试api调用.该代码几乎遵循redux文档的 Async Action Creators 部分中概述的模式:

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

要点是您使用 redux-mock-store 记录并断言任何触发的动作.

这是整个测试,使用nock模拟api调用:

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'))

        });

    });

});

但是似乎真正的lastFm api是在运行测试时调用的...真实数据是从lastFm返回的,而不是假的nock响应.

这是动作创建者本身:

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)
    }
}

断言失败,因为实时的lastFM响应与根据expectedActions对象期望的响应不同.

我尝试将nock分配给变量并将其注销.日志显示如下:

Nock似乎正在将端口80添加到url中,不确定是否会导致不模拟实际的API:

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

有什么想法吗?

解决方案

要使用nock,您必须在节点中运行测试(使用Jest或mocha),nock覆盖节点http的行为,因此,它仅在node中起作用而不是在浏览器(如PhantomJS)中.

例如,您指出的链接使用的是Jest,而第一行中明确显示了节点环境.因此,诺克将成为一种魅力. http://redux.js.org/docs/recipes/WritingTests.html

设置

我们建议Jest作为测试引擎.注意它运行 在Node环境中,因此您将无权访问DOM.

据我所见,您可以:

  • 在节点环境中运行测试
  • 或使用其他库进行模拟,例如 fetch-mock

I'm trying to test an api call in a redux app. The code pretty much follows the pattern outlined in the Async Action Creators section of the redux docs:

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

The gist of it is that you use redux-mock-store to record and assert against any actions that are triggered.

This is the whole test, using nock to mock 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 the real lastFm api is called when the test is run...real data is returned from lastFm rather than the fake nock response.

This is the action creator itself:

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 assertion fails because the live lastFM response is not the same as the response I'm expecting as per the expectedActions object..

I've tried assigning the nock to a variable and log it out.The log shows this:

Nock seems to be adding port 80 to the url, not sure if this is causing the actual API to not be mocked:

    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's wrong here?

解决方案

In order to use nock you must run your tests in node (using Jest or mocha), nock overrides node http behavior and for that reason it only works in node and not in browsers (like PhantomJS).

For example the link you pointed out is using Jest and first lines there are explicit about the node environment. Therefore, nock will work as a charm. http://redux.js.org/docs/recipes/WritingTests.html

Setting Up

We recommend Jest as the testing engine. Note that it runs in a Node environment, so you won't have access to the DOM.

As I see you can:

  • run your tests in a node environment
  • or use a different library to mock like fetch-mock

这篇关于Nock没有在Redux测试中拦截API调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆