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

[Redux-Observable && Unit Testing] Mocking an ajax request when testing epics的更多相关文章

  1. Extjs4.0以上版本 Ext.Ajax.request请求的返回问题

    Ext.Ajax.request({ url: posturl, method: 'POST', params: { ClassName: 'XXXX', FuncName: 'XXXX', para ...

  2. [转] form.getForm().submit的用法及Ext.Ajax.request的小小区别

    原文地址:http://blog.csdn.net/hongleidy5000/article/details/7329325 if (!formDetail.getForm().isValid()) ...

  3. (ExtJs 3.4)Ext.Ajax.request的同步请求实现

    ext3.0之前都是这样来提交:var responsea = Ext.lib.Ajax.getConnectionObject().conn;responsea.open("POST&qu ...

  4. Extjs-Ext.Ajax.request设置超时

    ExtJs的Ajax提交主要是:Ext.Ajax.request或form1.getForm().submit,超时时间默认是30秒. 很多时候,后台处理比较多,往往需要超出30秒的限制.此时,可以通 ...

  5. EXTJS 资料 Ext.Ajax.request 获取返回数据

    下面是一个登陆页面调用的EXTJS login function,通过 url: '/UI/HttpHandlerData/Login/Login.ashx',获取返回登陆账户和密码! Ext.onR ...

  6. Ext.Ajax.request()方法和FormPanel.getForm().submit()方法,都返回success()方法的差异

    我还是不发表到博客园首页吧,要不然还是要被取消,>_< 还是言归正传吧,关于Ext.Ajax.request()方法和FormPanel.getForm().submit()方法返回suc ...

  7. 【转】Ext.ajax.request 中的success和failure

    原文链接:Ext.ajax.request 中的success和failure Ajax request对象的success事件表示request过程中没有发生错误,和自己的业务逻辑无关, 如果访问不 ...

  8. Ext.Ajax.request同步请求

    导读: ajax分为2种,一种是同步,一种是异步同步:代码执行完了之后才执行后面的代码 异步:代码刚执行,后面的代码就马上接着执行了,不管前面的代码是否执行完异步的情况下,要获得返回信息,就需要在异步 ...

  9. Detecting an Ajax request in PHP

    1:index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...

随机推荐

  1. [Bug]Python3.x SyntaxError: 'ascii' codec can't decode byte 0xe4 in position

    安装arch后就没再用python了 昨天管服务器的大佬在跑贝叶斯分类器的时候发现正确率有问题 我赶紧去做优化,然后就有这样的报错 Python 3.6.4 (default, Jan 5 2018, ...

  2. 陌上开花(CDQ分治)

    题解 三维偏序裸题... 一般三维偏序是第一维排序,第二维CDQ分治,第三维树状数组. 模板题还是看代码吧... #include<iostream> #include<cstrin ...

  3. [CEOI2007]树的匹配Treasury(树形DP+高精)

    题意 给一棵树,你可以匹配有边相连的两个点,问你这棵树的最大匹配时多少,并且计算出有多少种最大匹配. N≤1000,其中40%的数据答案不超过 108 题解 显然的树形DP+高精. 这题是作为考试题考 ...

  4. 使用 swoole_process 实现 PHP 进程池

    swoole_process 主要是用来代替 PHP 的 pcntl 扩展.我们知道 pcntl 是用来进行多进程编程的,而 pcntl 只提供了 fork 这样原始的接口,容易使用错误,并且没有提供 ...

  5. 洛谷——P3374 【模板】树状数组 1

    https://www.luogu.org/problem/show?pid=3374 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某一个数加上x 2.求出某区间每一个数的和 输入输 ...

  6. 【Android进阶】Junit单元測试环境搭建以及简单有用

    单元測试的目的 首先.Junit单元測试要实现的功能,就是用来測试写好的方法是否可以正确的运行,一般多用于对业务方法的測试. 单元測试的环境配置 1.在AndroidManifest清单文件的Appl ...

  7. poj--1237--Drainage Ditches(最大流)

    Drainage Ditches Time Limit: 1000MS   Memory Limit: 10000KB   64bit IO Format: %I64d & %I64u Sub ...

  8. CentOS7 启动[root@localhost ~]# systemctl start docker Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for de

    1).在linux虚拟机上安装docker步骤:1.检查内核版本,必须是3.10及以上uname ‐r2.安装dockeryum install docker3.输入y确认安装4.启动docker[r ...

  9. AIX 系统补丁格式

    AIX 系统版本标准格式: 5300-06-11-0918 VR00-TL-SP-YYWW     5300-06-11-0918              ^-------- YYWW(2009年第 ...

  10. 2008R2域控环境中 应用组策略 实现禁用USB设备使用

    本文介绍如何在Windows Server 2008 AD中禁用客户端USB端口.本文使用的系统:Windows Server 2008 R2 企业版.域功能级别:Windows Server 200 ...