8

我正在尝试在 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

有什么想法吗?

4

3 回答 3

3

为了使用 nock,您必须在 node 中运行测试(使用 Jest 或 mocha),nock 会覆盖 node http 行为,因此它仅适用于 node 而不能在浏览器中(如 PhantomJS)。

例如,您指出的链接是使用 Jest 并且第一行是关于节点环境的明确说明。因此,诺克将作为一种魅力。 http://redux.js.org/docs/recipes/WritingTests.html

配置

我们推荐 Jest 作为测试引擎。请注意,它在 Node 环境中运行,因此您无法访问 DOM。

如我所见,您可以:

  • 在节点环境中运行测试
  • 或使用不同的库来模拟fetch-mock
于 2016-10-26T19:39:25.877 回答
0

在 nock 之后添加 .log(console.log) ,这样您将获得准确的预期和当前 url。例子:

     nock("http://localhost")
.log(console.log)
.persist()
.get("/api/config")
.reply(200, { data: 1234 })
于 2019-12-17T10:07:33.370 回答
0

您只需将基本 URL 传递给 mainnock函数,并将 URL 路径部分分离到.get()方法中。

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

我能够用上面的代码得到一个虚假的响应。

于 2016-03-26T20:58:53.457 回答