In certain situations, you care more about the final state of the redux store than you do about the particular stream of events coming out of an epic. In this lesson we explore a technique for dispatching actions direction into the store, having the epic execute as they would normally in production, and then assert on the updated store’s state.

To test a reducer, what we need to do is actually dispatch as action with its payload.

store.dispatch(action);

But before that, we need to get our 'store' configuration in the test.

configureStore.js:

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

index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import {Provider} from 'react-redux';
import {configureStore} from "./configureStore"; const store = configureStore(); ReactDOM.render(
<Provider store={store}>
<App />
</Provider>
, document.getElementById('root'));

The configureStore.js exports function which create a store, we can import normally in the test file.

Now for example, we want to dispatch this action:

export function searchBeers(query) {
return {
type: SEARCHED_BEERS,
payload: query
}
}

Epic:

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(500)
.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);

'decountTime' make the Epic async!

To verifiy the result is correct, we can do

  const store = configureStore(deps);

  const action = searchBeers('name');

  store.dispatch(action);

  expect(store.getState().beers.length).toBe();

BUT, actually this test code won't work, because the 'decountTime' in the epic, makes it as async opreation. Reducer expects everything happens sync...

One way can test it by using 'scheduler' from rxjs.

import {Observable} from 'rxjs';
import {VirtualTimeScheduler} from 'rxjs/scheduler/VirtualTimeScheduler';
import {searchBeers} from "../actions/index";
import {configureStore} from "../configureStore"; it('should perform a search (redux)', function () { const scheduler = new VirtualTimeScheduler();
const deps = {
scheduler,
ajax: {
getJSON: () => Observable.of([{name: 'shane'}])
}
}; const store = configureStore(deps); const action = searchBeers('shane'); store.dispatch(action); scheduler.flush(); expect(store.getState().beers.length).toBe();
});

And we need to modifiy the epic:

.debounceTime(, deps.scheduler)

Take away, we can test async oprations by using 'scheduler' from rxjs.

-------------------FUll Code------------

Github

[Redux-Observable && Unit Testing] Use tests to verify updates to the Redux store (rxjs scheduler)的更多相关文章

  1. Unit Testing with NSubstitute

    These are the contents of my training session about unit testing, and also have some introductions a ...

  2. [Java Basics3] XML, Unit testing

    What's the difference between DOM and SAX? DOM creates tree-like representation of the XML document ...

  3. Unit Testing PowerShell Code with Pester

    Summary: Guest blogger, Dave Wyatt, discusses using Pester to analyze small pieces of Windows PowerS ...

  4. C# Note36: .NET unit testing framework

    It’s usually good practice to have automated unit tests while developing your code. Doing so helps y ...

  5. Unit Testing of Spring MVC Controllers: “Normal” Controllers

    Original link: http://www.petrikainulainen.net/programming/spring-framework/unit-testing-of-spring-m ...

  6. Unit Testing, Integration Testing and Functional Testing

    转载自:https://codeutopia.net/blog/2015/04/11/what-are-unit-testing-integration-testing-and-functional- ...

  7. Javascript单元测试Unit Testing之QUnit

    body{ font: 16px/1.5em 微软雅黑,arial,verdana,helvetica,sans-serif; }           QUnit是一个基于JQuery的单元测试Uni ...

  8. [Unit Testing] AngularJS Unit Testing - Karma

    Install Karam: npm install -g karma npm install -g karma-cli Init Karam: karma init First test: 1. A ...

  9. C/C++ unit testing tools (39 found)---reference

    http://www.opensourcetesting.org/unit_c.php API Sanity AutoTest Description: An automatic generator ...

随机推荐

  1. MVC-easyui-EF

    easyui+jQuery+MVC+EF的一个演示 环境:visual studio 2013+sql server 创建新项目:visual C# -> Web -> visual st ...

  2. kolla-ansible 安装openstack 拉取阿里云镜像时报错

     TASK [mariadb : Pulling mariadb image] ************************************************************ ...

  3. whatis---查询一个命令执行什么功能

    whatis命令是用于查询一个命令执行什么功能,并将查询结果打印到终端上. whatis命令在用catman -w命令创建的数据库中查找command参数指定的命令.系统调用.库函数或特殊文件名.wh ...

  4. Oracle运行set autotrace on报错SP2-0618、SP2-0611

    SQL> set autotrace on SP2-0618: 无法找到会话标识符.启用检查 PLUSTRACE 角色 SP2-0611: 启用 STATISTICS 报告时出错 原因: PLU ...

  5. linux内核计算时间差以及jiffies溢出

    jiffies是每一个时钟中断,都会加1.这就导致一个问题.不管jiffies(一般来说是unsigned long类型)多少个字节,总有溢出的时候. 更极端的时候.当期jiffies是0xfffff ...

  6. css footer not displaying at the bottom of the page

    https://stackoverflow.com/questions/15960290/css-footer-not-displaying-at-the-bottom-of-the-page The ...

  7. android 客户端 Cookie处理

    Cookie,有时也用其复数形式Cookies,指某些网站为了辨别用户身份.进行session跟踪而储存在用户本地终端上的数据(通常经过加密). Cookie最早是网景公司的前雇员Lou Montul ...

  8. SQLHelper--java类

    package richard; import java.beans.Statement; import java.sql.Connection; import java.sql.DriverMana ...

  9. Beautiful Number

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2829 Beautiful Number Time Limit: 2 Sec ...

  10. SQLServer2008端口及防火墙设置

    一,Microsoft SQL Server 2008R2数据库设置 1.       开始=>程序=>Microsoft SQL Server 2008R2=>配置工具=>S ...