簡體   English   中英

如何確保僅在給定特定參數的情況下才調用方法

[英]How to make sure that a method is called only once given specific parameters

我有一個名為Feature的類,它包含以下方法setUser(boolean),execute(),doExecute()並且根據以下所述參數,當我調用execute()方法時,doExecute()方法應僅被調用一次。

我嘗試使用sinon在下面的代碼中測試doExecute()方法僅被調用一次,但是我收到一條錯誤消息:doExecute()方法被調用為零次。

請讓我知道如何正確檢查一次doExecute()是否被正確調用

代碼

t.context.clock = sinon.useFakeTimers();
const domain = 'testDomain';
const delayInMillis = 0;
const delayInSecs = delayInMillis / 1000;
const feature = new Feature(domain, delayInMillis);
feature.setUser(false);

const p = feature.execute()
 .then(() => sinon.spy(feature.doExecute()))
 .then(() => t.pass());

sinon.assert.callCount(sinon.spy(feature.doExecute()),1);
t.context.clock.restore();

return p;
});

首先, sinon.spy()接受一個function作為參數,然后傳遞函數的結果。

// wrong
sinon.spy(feature.doExecute());

// correct
sinon.spy(feature.doExecute);

接下來,您需要將間諜存儲到變量中以供以后參考。 在您的代碼中,您每次都只是在創建新的間諜。

const featureDoExecuteSpy = sinon.spy(feature.doExecute);

// some code

sinon.assert.callCount(featureDoExecuteSpy, 1);

這有很多問題。

正如sameeh指出的那樣,您只是在聲明中創建了一個新間諜。 顯然,一個新間諜的呼叫計數為零。 您需要確保斷言所引用的間諜實例與被測代碼將調用的間諜實例相同

然而,sameeh遺漏的關鍵是,必須將間諜傳遞給被測代碼。 這就是為什么通常的形式 “ sinon.spy()”接受一個對象,后跟一個方法名的原因。 它用包裹原始對象的間諜代替了該對象上的方法:

// wrong
sinon.spy(feature.doExecute());

// still wrong
sinon.spy(feature.doExecute);

// correct
sinon.spy(feature, 'doExecute');

然后,您可以訪問該對象上就位的間諜以進行斷言。 您無需將其存儲在本地變量中:

sinon.assert.callCount(feature.doExecute, 1);

另一個問題:您的斷言不是等待來自feature.execute的承諾解決。 這意味着,如果在execute一些異步操作之后調用了doExecute則斷言為時過早。 因此,它需要在then喜歡別人這么之后(注意,此代碼仍然不會因其他問題,我會在一個位地址工作):

const p = feature.execute()
 .then(() => sinon.spy(feature, 'doExecute'))
 .then(() => t.pass())
 .then(() => sinon.assert.callCount(feature.doExecute,1));

更多問題...您使用假計時器非常奇怪,這使我很難分辨出feature.execute()返回的諾言是否會解決。

是否需要計時器打勾才能解決? 不會的 因為您從來沒有打勾計時器。 我不知道t.pass()作用,但是由於它被鏈接到feature.execute()返回的promise上,所以如果您不在其他地方打勾,它將永遠不會被調用。 出於同樣的原因,您的代碼也不會創建間諜程序。

您需要調用feature.execute() 之前創建間諜,並可能在之后調用t.pass() ,如果它確實是在打假計時器的方法:

sinon.spy(feature, 'doExecute')

const p = feature.execute()
 .then(() => sinon.assert.callCount(feature.doExecute,1));

t.pass();

最后,我不知道您使用的是什么測試框架,但是無論測試是否成功,您通常都希望在將始終執行的塊中恢復假計時器和其他全局狀態。 這樣可以確保失敗的測試不會遺留下來的廢話,這些廢話會延續到其他測試中。 摩卡為此使用了beforeEachafterEach方法:

beforeEach(function() {
    t.context.clock = sinon.useFakeTimers();
});

afterEach(function() {
    t.context.clock.restore()
});

it('whatever your test name is', function() {
    const domain = 'testDomain';
    const delayInMillis = 0;
    const delayInSecs = delayInMillis / 1000;
    const feature = new Feature(domain, delayInMillis);

    sinon.spy(feature, 'doExecute')

    const p = feature.execute()
      .then(() => sinon.assert.callCount(feature.doExecute,1));

    t.pass();

    return p;
});

暫無
暫無

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

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