【问题标题】:mocha test mock/spy imported library using testdouble.jsmocha 使用 testdouble.js 测试模拟/间谍导入库
【发布时间】:2016-09-21 05:07:29
【问题描述】:

我的模块需要一个外部依赖项:downloadjs 导出一个函数而不是对象

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?

那我该如何测试这段代码呢?

【问题讨论】:

    标签: javascript node.js unit-testing


    【解决方案1】:

    您可以围绕存在于 3rd 方库(在本例中为下载js)中的功能创建一个包装器,并使用 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. 我使用了测试双存储库中提供的 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

    【讨论】:

    • 感谢您提供清晰的示例。所以包装器是不可测试的(需要集成测试)但对我来说很有意义:)
    • 包装器可以使用td.replace 在隔离/单元测试中进行测试,但是如果您想验证downloadjs 的实际功能,您将需要一个跨越该边界的更集成的测试。
    猜你喜欢
    • 2018-10-04
    • 2015-10-21
    • 1970-01-01
    • 2023-03-06
    • 2020-12-10
    • 1970-01-01
    • 1970-01-01
    • 2019-11-18
    • 2018-02-07
    相关资源
    最近更新 更多