2017-07-04 25 views
1

我是茉莉花的新手,非常抱歉,如果這是一個愚蠢的問題。爲什麼在用Jasmine測試異常時需要不同的語法?

我有一個這樣的測試...

it("should calculate factorial 5", function() { 
    expect(MathsUtils.fact(5)).toBe(120); 
}); 

這工作得很好。如果你傳遞一個負數我其實函數拋出一個異常,所以我試圖測試有以下...

it("should throw an exception when passed -1", function() { 
    expect(MathsUtils.fact(-1)).toThrow("n! does not exist for negative numbers"); 
}); 

但是這並沒有。經過一番搜索,我發現如果我改變這個測試看起來像這樣...

it("should throw an exception when passed -1", function() { 
    expect(function() { MathsUtils.fact(-1); }).toThrow("n! does not exist for negative numbers"); 
}); 

......它通過。但是,如果我以類似的方式更改我的第一個測試...

it("should calculate factorial 5", function() { 
    expect(function() { MathsUtils.fact(5); }).toBe(120); 
}); 

...它失敗。

爲什麼我需要兩種測試的不同語法?這兩者似乎都沒有爲另一方工作。

正如我所說的,我是茉莉花的新手,所以如果這在文檔中有介紹,請指向正確的方向,因爲我看不到任何解釋。

+1

這就是它的實現方式,你只需要像這樣使用它。你嘗試過'toThrowError' –

+3

因爲,**根據文檔**,*「'toThrow'匹配器用於測試函數是否拋出異常」*。否則,在實際調用* expect之前拋出異常*。 – jonrsharpe

+0

@VictoryOsikwemhe我試圖給ThrowError,但那也失敗了。你有鏈接到文檔?謝謝 –

回答

2

在該示例

expect(MathsUtils.fact(-1)) 

factexpect之前評估被調用,並且因此它不能捕捉異常,

其中

expect(function(){MathsUtils.fact(-1)}) 

expect是做執行並可以捕捉異常,因爲傳遞的是一個函數指針,而不是已經評估過的數值

+0

啊,這可能是@jonrsharpe的意思。我正要請他解釋一下。你有鏈接到這個文檔?我發現他們有點難以駕馭。謝謝 –

+1

沒有參考 - 這是一個JavaScript的東西,並沒有真正與茉莉花有關 - 任何在函數/閉包內的東西在接收方的後期評估 – Soren

+0

好吧,我想這是我對精細程度缺乏認識的地方Javascript的點開始顯示。我是白天的C#程序員,做一些網絡的東西作爲臨時演員。你知道我在哪裏可以找到更多關於這方面的信息。我想知道這是如何工作的。再次感謝 –

0

這是索倫答案中的評論附錄。

expect做執行,並可以捕獲該異常是什麼傳遞是一個函數指針,而不是一個已經評估值

以茉莉花2.6引擎蓋下看看:

當你call the expect() method幾件事情發生......

  1. Create the Expectationdefined here

  2. 「toThrow」匹配器定義了compare()方法,即mixed into the Expectation object

TL; DR:

  • toThrow()actual值,與expected值一起,被compare()呼叫通過。該值按功能調用within a try/catch block進行評估。

    function toThrow(util) { 
        return { 
        compare: function(actual, expected) { 
         var result = { pass: false }, 
         threw = false, 
         thrown; 
    
         if (typeof actual != 'function') { 
         throw new Error(getErrorMsg('Actual is not a Function')); 
         } 
    
         try { 
         actual(); 
         } catch (e) { 
         threw = true; 
         thrown = e; 
         } 
    
         if (!threw) { 
         result.message = 'Expected function to throw an exception.'; 
         return result; 
         } 
    
         // ... 
        } 
        } 
    } 
    
  • 爲什麼需要兩個測試不同的語法?這兩者似乎都沒有爲另一方工作。

    閱讀後toThrow()這應該更清楚。

    雖然拋出當創建原始類型等的數字或傳遞到,比方說,toBe()匹配器可以立即評估時,一個異常的「值」(即是threwthrown變量那裏)的字符串當不投擲時則爲。因此,馬克應該掌握執行的控制權。


    注意

    it("should throw", function() { 
        expect(someFunction()).toThrow("meh"); 
    }); 
    

    會因爲someFunction()半的工作可能會引發與套件將捕獲該異常並正在執行傳遞給it()關閉時報告規範失敗。

    但是既然在這種情況下既不調用expect()也不調用toThrow(),它不能檢查消息和類型(如toThrowError())。它只能檢測到規範失敗。


    這可以在運行的NodeJS或瀏覽器控制檯應該使它更加清楚小例子

    您也可以使自己的期望函數:

    // Expectation constructor 
    function Expectation(actual, reporter) { 
        this.actual = actual; 
        this.reporter = reporter; 
    } 
    
    // matcher "mixed in" 
    Expectation.prototype.toThrow = function(expected) { 
        try { 
         this.actual(); 
    
         // No exception thrown, this state is wrong 
         this.reporter(false, "Expected " + this.actual.name + " to throw but it did not throw"); 
        } catch(e) { 
         // This exception was expected, this state is correct 
    
         if (e.message !== expected) { 
          // But the message was wrong 
    
          this.reporter(false, "Expected " + this.actual.name + " to throw " + expected + " but it threw " + e.message); 
         } else { 
          // And its message was correct 
    
          this.reporter(true); 
         } 
        } 
    }; 
    
    // Helper to report (log) 
    function report(passed, msg) { 
        if (!passed) { 
         console.error(msg); 
        } else { 
         console.log("passed"); 
        } 
    } 
    
    // Helper to create expectation 
    function expect(actual) { 
        return new Expectation(actual, report); 
    } 
    
    > function correctError() { throw new Error("meh!"); } 
    > expect(correctError).toThrow("meh!"); 
    < passed 
    
    > function badMessageError() { throw new Error("hehe"); } 
    > expect(badMessageError).toThrow("meh!"); 
    < Expected badMessageError to throw meh! but it threw hehe 
    
    > function noError() { /* no action */ } 
    > expect(noError).toThrow("meh!"); 
    < Expected noError to throw but it did not throw 
    

    根據您的意見

    [...]我是C#程序[...]

    a nice C# answer類似的問題,實現像茉莉花一樣的行爲。

    相關問題