Mocha测试mock/spy导入库使用testdouble.js

mocha test mock/spy imported library using testdouble.js

本文关键字:testdouble js 导入 测试 mock spy Mocha      更新时间:2023-09-26

我的模块需要一个外部的dependencies: downloadjs导出一个函数而不是Object

import download from 'downloadjs' // download is a function

我的功能
const onExport = () => (dispatch, getState) => {
  let data = getState().get('data')
  let csv = mapDataToCsv(data)
  download(csv, "export-result.csv", "text/csv");
  // dispatch something else
}
单元测试

import download from 'downloadjs'
import td from 'testdouble'
// test case
it('unparse JSON to CSV', () => {
  td.replace('downloadjs') // no this doesn't work
  let store = createStore(reducer, initialState, middleware);
  store.dispatch(target.onExport()); // action calls
  let expected = td.matchers.contains('FOO,SUCCESS')
  // error it calls real download function not mock
  td.verify(download(expected, "export-result.csv", "text/csv")) 
  td.reset()
})

我尝试模拟/替换downloadjs以验证它是否使用有效数据调用。

td.replace(download)td.replace('downloadjs')都不工作

文档说你不应该模拟/替换外部库:

为什么td.replace()不能与外部CommonJS模块一起工作?

那么我如何测试这段代码?

您可以围绕第三方库(在本例中为downloadjs)中存在的功能创建一个包装器,并使用td.replace来模拟您的包装器。

函数

var downloadCSV = require('./downloadCSV.js')
module.exports = () => (dispatch, getState) => {
    downloadCSV('goats')
}

新的包装器依赖项

// downloadCSV.js
var download = require('downloadjs')
module.exports = (data) => {
    download(data, 'export-result.csv', 'text/csv')
}

describe('csv exporter', () => {
    var subject, downloadCSV
    beforeEach(() => {
        downloadCSV = td.replace('../../lib/downloadCSV.js')
        subject     = require('../../lib/code.js')
    })
    describe('downloading csv', () => {
        it('works', () => {
            subject()()
            td.verify(downloadCSV('goats'))
        })
    });
});
指出

  1. 注意subject()()的双重调用,因为你在测试代码中有一个函数返回一个函数。

  2. 我使用测试双repo中可用的node示例文件夹结构来构建这些测试:https://github.com/testdouble/testdouble.js/tree/master/examples/node

  3. 我已经上传了一个带有示例代码的存储库,供您使用。https://github.com/davemo/td-replace-helper

  4. 我没有包含Redux特定的代码,也没有使用ES6风格的导入,以避免在示例repo中引入太多依赖项。

  5. 为了方便td.replace的使用,你可能需要修改你对ES6样式导入的使用,查看这个评论线程了解更多信息:https://github.com/testdouble/testdouble.js/issues/51#issuecomment-207780628