Often in unit tests we are focussing on the logic involved in crafting a network request, & how we respond to the result. The external service is unlikely to be under our control, so we need a way to ‘mock’ the Ajax request in a way that allows us to focus on the logic. In this lesson we’ll see how we can pass in dependencies into epics to make testing things Ajax requests easier.

In a real world React app, for one epic, we might have some dependecies. For example, ajax call. To make it easy for testing, we can make those deps as injectable deps.

When creating root epic:

import { createEpicMiddleware, combineEpics } from 'redux-observable';
import { ajax } from 'rxjs/observable/dom/ajax';
import rootEpic from './somewhere'; const epicMiddleware = createEpicMiddleware(rootEpic, {
dependencies: { getJSON: ajax.getJSON }
});

Using it in Epic:

// Notice the third argument is our injected dependencies!
const fetchUserEpic = (action$, store, { getJSON }) =>
action$.ofType('FETCH_USER')
.mergeMap(({ payload }) =>
getJSON(`/api/users/${payload}`)
.map(response => ({
type: 'FETCH_USER_FULFILLED',
payload: response
}))
);

---------------Test example ---------------------

index.js, root setup

import {createStore, applyMiddleware, compose} from 'redux';
import {Provider} from 'react-redux';
import reducer from './reducers';
import { ajax } from 'rxjs/observable/dom/ajax'; import {createEpicMiddleware} from 'redux-observable';
import {rootEpic} from "./epics/index"; const epicMiddleware = createEpicMiddleware(rootEpic, {
dependencies: {
ajax
}
}); const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; const store = createStore(
reducer,
composeEnhancers(
applyMiddleware(epicMiddleware)
)
);

Epic function:

import {Observable} from 'rxjs';
import {combineEpics} from 'redux-observable';
import {CANCEL_SEARCH, receiveBeers, searchBeersError, searchBeersLoading, SEARCHED_BEERS} from "../actions/index"; const beers = `https://api.punkapi.com/v2/beers`;
const search = (term) => `${beers}?beer_name=${encodeURIComponent(term)}`; export function searchBeersEpic(action$, store, deps) {
return action$.ofType(SEARCHED_BEERS)
.debounceTime(, deps.scheduler)
.filter(action => action.payload !== '')
.switchMap(({payload}) => { // loading state in UI
const loading = Observable.of(searchBeersLoading(true)); // external API call
const request = deps.ajax.getJSON(search(payload))
.takeUntil(action$.ofType(CANCEL_SEARCH))
.map(receiveBeers)
.catch(err => {
return Observable.of(searchBeersError(err));
}); return Observable.concat(
loading,
request,
);
})
} export const rootEpic = combineEpics(searchBeersEpic);

Test code:

import {Observable} from 'rxjs';
import {ActionsObservable} from 'redux-observable';
import {searchBeersEpic} from "./index";
import {RECEIVED_BEERS, searchBeers, SEARCHED_BEERS_LOADING} from "../actions/index"; it.only('should perform a search', function () {
const action$ = ActionsObservable.of(searchBeers('shane')); const deps = {
ajax: {
getJSON: () => Observable.of([{name: 'shane'}])
}
}; const output$ = searchBeersEpic(action$, null, deps); output$.toArray().subscribe(actions => {
expect(actions.length).toBe(); expect(actions[].type).toBe(SEARCHED_BEERS_LOADING);
expect(actions[].type).toBe(RECEIVED_BEERS);
});
});

Refs: Link

最新文章

  1. EasyUI需注意的问题01
  2. window.showModalDialog返回值和window.open返回值实例详解
  3. 2016年10月27日--css样式表
  4. [转]关于 initWithNibName 和 loadNibNamed 的区别和联系
  5. 实现C#给系统其他窗口输入的思路
  6. 设计模式 - 策略模式(Strategy Pattern) 具体解释
  7. keybd_event函数用法
  8. 大数据系列修炼-Scala课程09
  9. 简说Python生态系统的14年演变
  10. ios手机访问H5页面中$(document).on绑定无效问题
  11. centos6.5 python命令行模式左右建无法使用
  12. 使用idea+springboot+Mybatis搭建web项目
  13. Mybatis 使用了哪些设计模式?
  14. “数学口袋精灵”App的第三个Sprint计划----开发日记(第十一天12.17)
  15. Vue插件写、用详解(附demo)
  16. 用 CPI 火焰图分析 Linux 性能问题
  17. JAVA代码MD5加密方法
  18. TensorFlow随机值:tf.random_normal函数
  19. rap 部署
  20. JAVA-jar包下载地址

热门文章

  1. Win10+CUDA9.0+cuDNN7.2 下载 安装 配置
  2. 【Henu ACM Round#19 B】 Luxurious Houses
  3. gcc 生成动态链接库
  4. Codeforces Round #313 C. Gerald's Hexagon(放三角形)
  5. UI_UISegmentedControl 控件
  6. Hadoop2.2集群安装配置-Spark集群安装部署
  7. java内部类的初始化
  8. .net 项目分层及规范
  9. Chromium Graphics : GPU Accelerated Compositing in Chrome
  10. js002---- 标准内置对象