如何使用 Jest 和 Sinon 测试 Thunk 动作

Posted

技术标签:

【中文标题】如何使用 Jest 和 Sinon 测试 Thunk 动作【英文标题】:How to test Thunk actions with Jest and Sinon 【发布时间】:2017-09-14 21:35:28 【问题描述】:

我正在创建一个简单的操作来使用 Thunk 从 API 获取一些数据。它看起来像这样:

import fetch from 'isomorphic-fetch';

function json(response) 
  return response.json();


/**
 * Fetches books from the server
 */
export function getBooks() 
  return function(dispatch) 
    fetch("http://localhost:1357/book", mode: "cors")
    .then(json)
    .then(function(data) 
      dispatch(
        type: "GET_BOOKS",
        devices: data
      );
    );
  
;

它应该调用一次fetch。我已经验证它可以做到这一点,因为它在 Web 浏览器中调用时成功提取数据。但是,当我写这个测试时:

import fetch from 'isomorphic-fetch';
let spy = sinon.spy(fetch);
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import getBooks from '../../actions/getBooks';
import sinon from 'sinon';

const middlewares = [ thunk ];
const mockStore = configureMockStore(middlewares);

describe('async actions', () => 

  it('calls the server', () => 
    const store = mockStore(books: []);
    store.dispatch(getBooks());
      expect(spy.callCount).toEqual(1);
      spy.restore();
  );
);

但是,此测试失败,spy 的调用计数为 0。我怀疑这是由于测试前的操作导入了 fetch,这就是为什么在文件顶部创建 spy .但是,这不起作用。测试 fetch 是否被调用的推荐方法是什么?

【问题讨论】:

【参考方案1】:

从http://arnaudbenard.com/redux-mock-store/ 读取,部分异步操作。

我猜这是因为您没有在测试中使用 Promise。

it('calls the server', (done) => 
    const store = mockStore(books: []);
    store.dispatch(getBooks()).then(() => 
      expect(spy.callCount).toEqual(1);
      spy.restore();
      done();
    );
  );

【讨论】:

感谢您的帮助!当我运行测试时,我收到一条错误消息cannot read property 'then' of undefined。我假设这意味着商店没有定义,但我们确实定义了它。知道为什么会这样吗? 没关系 - 我不得不将代码改为 return fetch(localhost... 而不仅仅是 fetch(localhost...

以上是关于如何使用 Jest 和 Sinon 测试 Thunk 动作的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 sinon 存根/模拟从“超类”复制的依赖项方法

前端自动化测试框架 Jest 极简教程

使用 Sinon 进行单元测试:如何在回调中测试变量?

如何在 Jasmine 单元测试中使用 Sinon 对 jQuery 动画进行假时间?

如何用 Jest 模拟/替换对象的 getter 函数?

记一次简单的vue组件单元测试