web-dev-qa-db-ja.com

Sinon-スタブモジュールの機能と依存性注入なしでテスト

関数呼び出しをサービスに転送するプロキシモジュールがあります。このプロキシモジュールの関数が呼び出されたときに、サービス関数が呼び出されるかどうかをテストしたいと思います。

プロキシモジュールは次のとおりです。

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

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

module.exports = entity

この例 および この応答 に基づいて、必要なモジュール '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)

しかし、それは目的をテストするためだけに追加されたコードです。依存性の注入や回避策なしでモジュール関数をスタブ化する方法はありますか?

5
AFMeirelles

問題は、payServiceがすでにマッピングを設定した後、entityをスタブするのが遅すぎることです。

テストコードを次のように変更した場合:

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がスタブ関数でセットアップされ、アサーションが正常に渡されることがわかります。

5
Phil Booth