Nock 在 Redux 测试中没有拦截 API 调用
Posted
技术标签:
【中文标题】Nock 在 Redux 测试中没有拦截 API 调用【英文标题】:Nock is not intercepting API call in Redux test 【发布时间】:2016-07-14 10:12:32 【问题描述】:我正在尝试在 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: ObjectGET http://ws.audioscrobbler.com:80/2.0/?
method=artist.search&artist=john&api_key=abc123&format=json&limit=5
有什么想法吗?
【问题讨论】:
你是在节点还是浏览器中运行这个?我不相信 nock 在浏览器中有效,只有节点 啊好吧,那就是问题所在,我正在 PhantomJs 上运行测试 看起来 nock 不喜欢浏览器获取 github.com/node-nock/nock/issues/409。暂时按照建议尝试切换到 fetch-mock 你找到答案了吗?我到处找了,都想不通 您找到解决方案了吗?我的诺克也不是在嘲笑。 【参考方案1】:在 nock 之后添加 .log(console.log) ,这样您将获得准确的预期和当前 url。 示例:
nock("http://localhost")
.log(console.log)
.persist()
.get("/api/config")
.reply(200, data: 1234 )
【讨论】:
【参考方案2】:要使用 nock,您必须在 node 中运行测试(使用 Jest 或 mocha),nock 会覆盖 node http 行为,因此它仅适用于 node 而不能在浏览器中(如 PhantomJS)。
例如,您指出的链接是使用 Jest 并且第一行是关于节点环境的明确说明。因此,诺克将作为一种魅力。 http://redux.js.org/docs/recipes/WritingTests.html
设置
我们推荐 Jest 作为测试引擎。请注意,它运行 在 Node 环境中,因此您将无法访问 DOM。
我认为你可以:
在节点环境中运行测试 或使用不同的库模拟fetch-mock【讨论】:
【参考方案3】:您只需将基本 URL 传递给主 nock
函数,并将 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)
我能够用上面的代码得到一个虚假的响应。
【讨论】:
我应该提到我已经尝试过这个 - 我仍然使用这个配置从最后一个 fm 获取真实数据 好吧,你需要发布一个MCVE,因为这里还有其他断开连接的东西,但很难猜出那可能是什么。 好的,添加了更多细节 看起来 url 路径不匹配 /202/ vs /2.0/ 不幸的是,这是一个错字以上是关于Nock 在 Redux 测试中没有拦截 API 调用的主要内容,如果未能解决你的问题,请参考以下文章
错误:在带有 nock 和 mock-store 的 Redux 应用程序的异步操作测试中,操作可能未定义
Redux 使用 jest、nock、axios 和 jsdom 测试 multipart/form-data