【问题标题】:Sinon - Stub module function and test it without dependency injectionSinon - Stub 模块功能并在没有依赖注入的情况下对其进行测试
【发布时间】:2018-04-19 20:09:10
【问题描述】:

我有一个代理模块,它将函数调用转发给服务。我想测试是否调用了服务函数,当这个代理模块中的一个函数被调用时。

这里是代理模块:

const payService = require('../services/pay')
const walletService = require('../services/wallet')

const entity = {
    chargeCard: payService.payByCardToken,
    // ... some other fn
}

module.exports = entity

基于this examplethis response,我尝试存根所需的模块“payService”:

const expect = require('expect.js')
const sinon = require('sinon') 
const entity = require('../entity')
const payService = require('../../services/pay')

describe('Payment entity,', () => {

    it('should proxy functions to each service', () => {

        const stub = sinon.stub(payService, 'payByCardToken')
        entity.chargeCard()
        expect(payService.payByCardToken.called).to.be.ok()

    })
})

但测试失败:

  0 passing (19ms)
  1 failing

  1) Payment entity,
       should proxy functions to each service:
     Error: expected false to be truthy
      at Assertion.assert (node_modules/expect.js/index.js:96:13)
      at Assertion.ok (node_modules/expect.js/index.js:115:10)
      at Function.ok (node_modules/expect.js/index.js:499:17)
      at Context.it (payments/test/entity.js:14:56)

那是因为 payService 模块并没有真正被存根。我知道如果我将 payService 添加为实体的属性并用函数包装所有内容,测试将通过:

// entity
const entity = () => {
    return {
        payService,
        chargeCard: payService.payByCardToken,
        // .. some other fn
    }
}

// test
const stub = sinon.stub(payService, 'payByCardToken')
entity().chargeCard()
expect(payService.payByCardToken.called).to.be.ok()

// test output
Payment entity,
  ✓ should proxy functions to each service

1 passing (8ms)

但那是仅为测试目的而添加的代码。有没有办法在没有依赖注入和解决方法的情况下存根模块功能?

【问题讨论】:

    标签: javascript node.js unit-testing sinon stub


    【解决方案1】:

    问题是在entity 已经设置了它的映射之后,你对payService 存根太晚了。

    如果您像这样更改测试代码:

    const expect = require('expect.js')
    const sinon = require('sinon') 
    const payService = require('../../services/pay')
    
    describe('Payment entity,', () => {
        let entity
    
        before(() => {
            sinon.stub(payService, 'payByCardToken')
            entity = require('../entity')
        })
    
        it('should proxy functions to each service', () => {
            entity.chargeCard()
            expect(payService.payByCardToken.called).to.be.ok()
        })
    })
    

    ...您应该会发现 entity 使用您的存根函数设置了自己,并且断言正常通过。

    【讨论】:

    • 如果 payService 是一个模块(有一堆例程,而不是一个类,其测试实例随着测试结束而消失......)记得.restore()删除存根以避免副作用下次测试……
    • 在哪里可以阅读有关此主题的更多信息?为什么初始代码不起作用?在运行时做 requires 是个好主意吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-18
    • 2020-12-08
    • 2018-07-12
    相关资源
    最近更新 更多