2016-09-19 24 views
3

我按照redux.org的基本〔实施例测试异步操作终极版 - 如何利用箭扣测试异步操作

action.js

我的代码是这样的:

import axios from 'axios' 

export function getGoodDataStart(){ 
    return{ 
     type: "GOOD_DATA_START" 
    } 
} 
export function getGoodDataSuccess(payload){ 
    console.log('success', payload) 
    return { 
     type: "GOOD_DATA_SUCCESS", 
     payload: payload 
    } 
} 
export function getGoodDataFail(){ 
    return{ 
     type: "GOOD_DATA_FAIL" 
    } 
} 
export function getGoodData(){ 
    return (dispatch) => { 
     dispatch(getGoodDataStart()) 
     return axios.get('http://www.google.com/list') 
      .then(response => { 
       console.log('fake res',response) 
       dispatch(getGoodDataSuccess (response)) 
      }) 
      .catch(err => { 
       console.log('fake err',err) 
      }) 
    } 
} 

测试.js

import nock from 'nock' 
import React from 'react' 
import {expect} from 'chai' 
import {getGoodData} from 'registerAction' 
import configureMockStore from 'redux-mock-store' 
import thunk from 'redux-thunk' 

const middlewares = [ thunk ] 
const mockStore = configureMockStore(middlewares) 

describe('Register component',() => { 

    it('async action', function() { 

     nock('http://www.google.com') 
     .get('/list') 
     .reply(200,'ok!') 

     const store = mockStore({ 
      myData: '' , 
     }) 
     const expected = [ 
      {type: "GOOD_DATA_START"}, 
      {type: "GOOD_DATA_SUCCESS", payload: 'ok!'} 
     ] 

     return store.dispatch(getGoodData()) 
      .then(() => { 
       expect(store.getActions()).to.equal(expected) 
      }) 
    }) 
}) 

我现在的问题是,nock没有阻塞请求,它让函数getGoodData使得r eal请求到google.com。我究竟做错了什么?

错误的屏幕截图:

enter image description here

以下是演示:https://github.com/craigcosmo/react-redux-test

安装:NPM我

测试:NPM运行测试

打开URL: http://localhost:5051/webpack-dev-server/

+0

我想可能是因为你有一个尾随'/'在'nock'设置。而不是'nock'('http://example.com/')'do'nock('http://example.com')':) –

+0

删除了'/'仍然没有帮助 –

+0

你确定你正在击中/插入完全相同的端点? –

回答

1

阅读https://github.com/node-nock/nock/issues/150

你的测试是在控制台 -

做的很好补充这两脚本在您的package.json运行

"itest": "mocha --compilers js:babel-register -R spec \"test/*.test.js\"", 
    "itest:watch": "npm run itest -- --watch" 
+0

我添加了两个命令。运行'itest'时出现错误。错误:无法找到模块'./options' –

+0

您是如何在控制台中运行测试的? –

0

您可能需要像这样

beforeEach(() => { 
    nock.disableNetConnect(); 
}); 

afterEach(() => { 
    nock.cleanAll(); 
    nock.enableNetConnect(); 
}); 

Enable/Disable real HTTP Request

+0

该解决方案存在同样的问题,该操作仍在进行实际的请求。 –

+0

@angry_kiwi你是否在运行应用程序而不是测试,并期望nock拦截它?诺克只能设置为在测试中工作。 – yjcxy12

+0

我正在运行测试 –

3

通常,在测试这样的动作时,您需要从等式中删除不属于您的动作的任何内容。在这种情况下,通过简单地使用nock,你不会从等式中删除axios,并且实际上增加了不必要的复杂性。通过与间谍嘲笑axios,你可以避免打网络电话,你也可以避免调用axios。这使您可以简单地声明使用正确的参数调用axios。间谍可以返回一个承诺,允许测试所有的承诺处理和随后的动作调用。为了证明这一点,我需要添加一个提供间谍的库,所以我选择为断言和间谍添加“期望”,但是如果你想坚持chai,你可以轻松地用sinon做同样的事情。

这里有一个例子,你不都需要箭扣和一个间谍,你只是模拟Axios公司:

import React from 'react' 
import * as registerAction from 'registerAction' 
import configureMockStore from 'redux-mock-store' 
import thunk from 'redux-thunk' 
import expect from 'expect' 

const middlewares = [ thunk ] 
const mockStore = configureMockStore(middlewares) 

// set up to mock axios methods 
import axios from 'axios' 
const _get = axios.get 

const fakePayload = { foo: 'bar' }; 
describe('Register component',() => { 
    beforeEach(() => { 
     // replace the .get method temporarily with a spy 
     axios.get = expect.createSpy().andReturn(Promise.resolve(fakePayload)); 
    }) 

    afterEach(() => { 
     // restore the get method with our saved const 
     axios.get = _get; 
    }) 

    it('async action', function() { 
     const store = mockStore({ 
      myData: '' , 
     }) 
     const expected = [ 
      {type: "GOOD_DATA_START"}, 
      {type: "GOOD_DATA_SUCCESS", payload: fakePayload} 
     ] 

     return store.dispatch(registerAction.getGoodData()) 
      .then(() => { 
       expect(store.getActions()).toEqual(expected) 
       expect(axios.get).toHaveBeenCalled() 
       expect(axios.get).toHaveBeenCalledWith('http://www.google.com/list') 
      }) 
    }) 
})