4

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

test.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 が google.com に実際のリクエストを行うことができます。私は何を間違っていますか?

エラーのスクリーンショット:

ここに画像の説明を入力

デモは次のとおりです: https://github.com/craigcosmo/react-redux-test

インストール: npm i

テストする: npm run test

開く URL: http://localhost:5051/webpack-dev-server/

4

3 に答える 3

3

通常、このようなアクションをテストするときは、アクションの一部ではないものを方程式から削除する必要があります。この場合、nock を使用するだけでは、方程式から axios を削除するのではなく、実際には不必要な複雑さを追加しています。スパイを使用して axios をモックすることで、ネットワーク呼び出しを回避し、axios の呼び出しもまったく回避できます。これにより、axios が正しいパラメーターで呼び出されていることを簡単にアサートできます。スパイは、すべてのプロミス処理と後続のアクション コールをテストできるプロミスを返すことができます。これを実証するために、スパイを提供するライブラリを追加する必要があったため、アサーションとスパイの両方に「expect」を追加することを選択しましたが、chai に固執したい場合は、sinon で同じことを簡単に行うことができます。

これは、nock をまったく必要とせず、スパイで 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')
            })
    })
})
于 2016-10-15T18:24:47.240 に答える
2

https://github.com/node-nock/nock/issues/150を読む

あなたのテストはコンソールでうまくいっています-

package.json で実行されるこの 2 つのスクリプトを追加します。

    "itest": "mocha --compilers js:babel-register -R spec  \"test/*.test.js\"",
    "itest:watch": "npm run itest -- --watch"
于 2016-09-21T19:44:20.863 に答える