使用testdouble.js进行mocha测试模拟/间谍导入库

时间:2016-09-21 05:07:30

标签: javascript node.js unit-testing

我的模块需要一个外部依赖项: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')都不起作用

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

Why doesn't td.replace() work with external CommonJS modules?

然后如何测试此代码?

1 个答案:

答案 0 :(得分:5)

您可以围绕第三方库中存在的功能创建包装器(在本例中为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. 我使用了test double repo中提供的node示例文件夹结构来构建这些测试:https://github.com/testdouble/testdouble.js/tree/master/examples/node

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

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

  5. 您可能需要按摩ES6样式导入的使用以便于td.replace的使用,请查看此评论主题以获取更多信息:https://github.com/testdouble/testdouble.js/issues/51#issuecomment-207780628