簡體   English   中英

無法使用Sinon存根函數

[英]Unable to stub a function using Sinon

我有一個Redux動作,它本身會調度其他兩個動作。 每個操作均從導入的函數中檢索。 一個來自本地模塊,另一個來自外部庫。

import { functionA } from './moduleA';
import { functionB } from 'libraryB';

export function myAction() {
  return (dispatch) => {
    dispatch(functionA());
    ...
    dispatch(functionB());
  }
}

在我的測試中,我使用sinon沙箱對功能進行了測試,但是只有兩個測試通過了。 我希望所有三個都通過。

import * as A from './moduleA';
import * as B from 'libraryB';

describe(__filename, async () => {
  it('Calls 2 other actions', () => {
    sandbox = sinon.sandbox.create();

    const dispatch = sandbox.stub();

    sandbox.stub(A, 'functionA');
    sandbox.stub(B, 'functionB');

    await myAction()(dispatch);

    // passes
    expect(dispatch.callCount).to.equal(2);

    //passes
    expect(A.functionA).to.have.been.called();

    // fails
    expect(B.functionB).to.have.been.called();     
  });
});

最后的期望因錯誤而失敗:

TypeError:[Function:functionB]不是間諜,也不是間諜!

當我將功能輸出到控制台時,我得到了這一點,這似乎與Babel導入導出導出的方式有關(將ES6重新導出的值包裝到Getter中 )。 這些功能可以實時運行,只是不在測試中。

{ functionA: [Function: functionA] }
{ functionB: [Getter] }

我試過使用stub.get(getterFn)但這只是給我錯誤:

TypeError:無法重新定義屬性:fetchTopicAnnotations

您是否嘗試過命名存根? 您的代碼有點怪異。 在測試中的任何時候,您都不是指存根。

import * as A from './moduleA';
import * as B from 'libraryB';

describe(__filename, async () => {
  it('Calls 2 other actions', () => {
    sandbox = sinon.sandbox.create();

    const dispatch = sandbox.stub();

    const functionAStub = sandbox.stub(A, 'functionA');
    const functionBStub = sandbox.stub(B, 'functionB');

    await myAction()(dispatch);

    // passes
    expect(dispatch.callCount).to.equal(2);

    //passes
    expect(functionAStub.called).toBe(true);

    // fails
    expect(functionBStub.called).toBe(true);     
  });
});

很難說是100%,但是看來該模塊正在導入,因此在進行測試存根之前直接引用了該功能。 Sinon將有效地替換導出對象上的函數,但另一個模塊將首先導入並獲得對實函數的引用,替換它不會導致重新加載。

您可以對其進行試驗並通過將其更改為以下模塊來證明這一點:

import * as A from './moduleA';
import * as B from 'libraryB';

export function myAction() {
  return (dispatch) => {
    dispatch(A.functionA());
    ...
    dispatch(B.functionB());
  }
}

從本質上講,這將在調用時查找對functionA / functionB的引用,這將使您可以用存根替換它們。

如果您發現這很重要,並且想要保留原始格式,那么我相信您需要使用另一個名為proxyquire庫,它將有效地使您存根要導入的整個模塊。

您的測試功能最終看起來像這樣:

import * as proxyquire from 'proxyquire'
// import * as A from './moduleA'
// import * as B from 'libraryB'

describe(__filename, async () => {
  const A = {}
  const B = {}
  const functionAStub = sandbox.stub(A, 'functionA')
  const functionBStub = sandbox.stub(B, 'functionB')
  const { myAction } = proxyquire('./myAction', {
    './moduleA': A,
    'libraryB': B
  })
  ...
})

在需要該模塊時,直到您調用proxyquire時,該模塊才會被導入,它將使用存根模塊而不是真實模塊。

然后,您可以按預期從測試中引用這些存根。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM