我正在尝试在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,不确定这是否导致实际的API不被模拟:
keyedInterceptors: Object{GET http://ws.audioscrobbler.com:80/2.0/?
method=artist.search&artist=john&api_key=abc123&format=json&limit=5
这里有什么想法吗?
答案 0 :(得分:3)
为了使用nock,你必须在节点中运行测试(使用Jest或mocha),nock覆盖节点http行为,因此它只能在节点中工作,而不能在浏览器中工作(如PhantomJS)。
例如,您指出的链接是使用Jest,第一行显示有关节点环境的信息。因此,诺克将成为一种魅力。 http://redux.js.org/docs/recipes/WritingTests.html
设置
我们建议Jest作为测试引擎。请注意它运行 在Node环境中,您无法访问DOM。
我认为你可以:
答案 1 :(得分:0)
您只需将基本网址传递给主nock
功能,并将网址路径部分分隔为.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})
我能够使用上面的代码得到一个假响应。
答案 2 :(得分:0)
在nock之后添加.log(console.log),因此您将获得确切的预期和当前URL。 例如:
nock("http://localhost")
.log(console.log)
.persist()
.get("/api/config")
.reply(200, { data: 1234 })