[英]How to compare (anonymous) function in jest tests?
我將以下 React 組件連接到 redux 存儲。
import React, { Component } from 'react'
import logo from './logo.svg'
import './App.css'
import { connect } from 'react-redux'
import { getWeather } from './actions/WeatherActions'
import WeatherComponent from './components/weatherComponent/WeatherComponent'
import { get } from 'lodash'
export class App extends Component {
componentDidMount () {
this.props.dispatch(getWeather())
}
render () {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
<WeatherComponent
weather={{
location: get(this.props.weatherReducer.weather, 'name'),
temp: get(this.props.weatherReducer.weather, 'main.temp')
}}
/>
</div>
)
}
}
export default connect((store) => {
return {
weatherReducer: store.weatherReducer,
}
})(App)
此組件使用componentDidMount回調分派getWeather操作。 getWeather操作在解析 axios 承諾時返回一個匿名方法。
import { GET_WEATHER_DONE, GET_WEATHER_ERROR } from './ActionTypes'
import axios from 'axios'
export function getWeather () {
let endpoint = 'http://api.openweathermap.org/data/2.5/weather?q=London&appid=2a345681ddcde393253af927097f5747'
return function (dispatch) {
return axios.get(endpoint)
.then((response) => {
return dispatch({
type: GET_WEATHER_DONE,
payload: response.data
})
})
.catch((error) => {
return dispatch({
type: GET_WEATHER_ERROR,
payload: error.response.data,
statuscode: error.response.status
})
})
}
}
不,我正在嘗試編寫一個單元測試來驗證getWeather操作是否在安裝時被分派。 該測試如下所示並通過。
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
import * as actions from './actions/WeatherActions'
describe('app container', () => {
const store = configureMockStore([thunk])({
weatherReducer: {
weather: {}
}
})
const dispatchSpy = jest.fn()
store.dispatch = dispatchSpy
it('dispatches getWeather() action upon rendering', () => {
ReactDOM.render(<App store={store} />, document.createElement('div'))
expect(dispatchSpy.mock.calls[0][0].toString()).toEqual(actions.getWeather().toString())
})
})
由於操作返回匿名方法,我需要在模擬上調用toString方法來比較操作。
我使用快照測試重新創建了這個測試。
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
describe('app container', () => {
const store = configureMockStore([thunk])({
weatherReducer: {
weather: {}
}
})
const dispatchSpy = jest.fn()
store.dispatch = dispatchSpy
it('dispatches correct actions upon rendering', () => {
ReactDOM.render(<App store={store} />, document.createElement('div'))
let tree = dispatchSpy.mock.calls.toString()
expect(tree).toMatchSnapshot();
})
})
我再次需要調用toString方法,從而生成以下快照。
// Jest Snapshot v1,
exports[`app container dispatches correct actions upon rendering 1`] = `
"function (dispatch) {
return _axios2.default.get(endpoint).
then(response => {
return dispatch({
type: _ActionTypes.GET_WEATHER_DONE,
payload: response.data });
}).
catch(error => {
return dispatch({
type: _ActionTypes.GET_WEATHER_ERROR,
payload: error.response.data,
statuscode: error.response.status });
});
}"
`;
現在,當運行覆蓋率時,使用紗線測試 -- --coverage ,我的測試失敗了,因為 istanbul 在我的操作中添加了文本。 輸出如下所示:
FAIL src/App.snapshot.test.js
● app container › dispatches correct actions upon rendering
expect(value).toMatchSnapshot()
Received value does not match stored snapshot 1.
- Snapshot
+ Received
-"function (dispatch) {
- return _axios2.default.get(endpoint).
- then(response => {
- return dispatch({
- type: _ActionTypes.GET_WEATHER_DONE,
- payload: response.data });
+"function (dispatch) {/* istanbul ignore next */cov_2rypo7bhf.f[1]++;cov_2rypo7bhf.s[2]++;
+ return (/* istanbul ignore next */_axios2.default.get(endpoint).
+ then(response => {/* istanbul ignore next */cov_2rypo7bhf.f[2]++;cov_2rypo7bhf.s[3]++;
+ return dispatch({
+ type: /* istanbul ignore next */_ActionTypes.GET_WEATHER_DONE,
+ payload: response.data });
- }).
- catch(error => {
- return dispatch({
- type: _ActionTypes.GET_WEATHER_ERROR,
- payload: error.response.data,
- statuscode: error.response.status });
+ }).
+ catch(error => {/* istanbul ignore next */cov_2rypo7bhf.f[3]++;cov_2rypo7bhf.s[4]++;
+ return dispatch({
+ type: /* istanbul ignore next */_ActionTypes.GET_WEATHER_ERROR,
+ payload: error.response.data,
+ statuscode: error.response.status });
- });
+ }));
}"
at Object.it (src/App.snapshot.test.js:21:18)
at Promise.resolve.then.el (node_modules/p-map/index.js:46:16)
我面臨的主要問題是我需要調用toString方法進行比較。 在玩笑測試中比較(匿名)函數的正確方法是什么?
完整源代碼可以在https://github.com/wvanvlaenderen/react-redux-weathercomponent找到
因此,我能夠通過在我的測試中模擬 getWeather 操作並驗證各個調用的返回值類型來測試調度調用。
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
import * as actions from './actions/WeatherActions'
import { spy } from 'sinon'
describe('app container', () => {
const store = configureMockStore([thunk])({
weatherReducer: {
weather: {}
}
})
const dispatchSpy = spy(store, 'dispatch')
actions.getWeather = jest.fn().mockImplementation(() => {
return {type: 'fetching weather'}
})
it('dispatches getWeather() action upon rendering', () => {
ReactDOM.render(<App store={store} />, document.createElement('div'))
expect(dispatchSpy.firstCall.returnValue.type).toEqual('fetching weather')
})
})
快照測試是通過在調度間諜上渲染調用樹來實現的。
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import { spy } from 'sinon'
import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
import * as actions from './actions/WeatherActions'
describe('app container', () => {
const store = configureMockStore([thunk])({
weatherReducer: {
weather: {}
}
})
const dispatchSpy = spy(store, 'dispatch')
actions.getWeather = jest.fn().mockImplementation(() => {
return {type: 'fetching weather'}
})
it('dispatches correct actions upon rendering', () => {
ReactDOM.render(<App store={store} />, document.createElement('div'))
expect(dispatchSpy.getCalls()).toMatchSnapshot();
})
})
使用 Jest 測試 redux thunk 時,我使用了expect.any(Function)
。 所有斷言庫都有這樣的東西。
例如)
行動
const toggleFilter = (toggle, isShown) => {
return dispatch => {
toggle === 'TOGGLE ONE'
? dispatch(toggleSwitchOne(isShown))
: dispatch(toggleSwitchTwo(isShown));
};
};
測試文件:
beforeEach(() => {
store = mockStore({ showFruit: false, showVeg: false });
dispatch = jest.fn();
getState = () => store;
})
it('will dispatch action to toggle switch', () => {
let res = toggleFilter(type, isShown)(dispatch, getState);
expect(dispatch).toHaveBeenCalledTimes(1);
expect(dispatch).toHaveBeenCalledWith(expect.any(Function));
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.