जेस्ट में फेंके गए अपवाद के प्रकार का परीक्षण कैसे करें


161

मैं कुछ कोड के साथ काम कर रहा हूं, जहां मुझे फ़ंक्शन द्वारा फेंके गए अपवाद के प्रकार का परीक्षण करने की आवश्यकता है (क्या यह टाइपर्र, रेफरेंस इत्यादि है)।

मेरा वर्तमान परीक्षण ढांचा AVA है और मैं इसे दूसरे तर्क t.throwsविधि के रूप में परख सकता हूं , जैसे:

it('should throw Error with message \'UNKNOWN ERROR\' when no params were passed', (t) => {
  const error = t.throws(() => {
    throwError();
  }, TypeError);

  t.is(error.message, 'UNKNOWN ERROR');
});

मैंने जेस्ट को अपने परीक्षण फिर से लिखना शुरू कर दिया और आसानी से ऐसा करने के लिए नहीं मिला। क्या यह भी संभव है?

जवाबों:


225

जेस्ट में आपको एक फ़ंक्शन को अपेक्षा (फ़ंक्शन) .toThrow (रिक्त या त्रुटि के प्रकार) में पास करना होगा।

उदाहरण:

test("Test description", () => {
  const t = () => {
    throw new TypeError();
  };
  expect(t).toThrow(TypeError);
});

यदि आपको किसी मौजूदा फ़ंक्शन का परीक्षण करने की आवश्यकता है, चाहे वह तर्कों के एक सेट के साथ फेंकता है, तो आपको इसे एक अनाम फ़ंक्शन के अंदर अपेक्षा में लपेटना होगा ()।

उदाहरण:

test("Test description", () => {
  expect(() => {http.get(yourUrl, yourCallbackFn)}).toThrow(TypeError);
});

79

थोड़ा अजीब है, लेकिन काम करता है और इहो अच्छा पठनीय है:

it('should throw Error with message \'UNKNOWN ERROR\' when no params were passed', () => {
  try {
      throwError();
      // Fail test if above expression doesn't throw anything.
      expect(true).toBe(false);
  } catch (e) {
      expect(e.message).toBe("UNKNOWN ERROR");
  }
});

Catchब्लॉक अपने अपवाद को पकड़ें, फिर आप अपने उठाए हुए पर परीक्षण कर सकते हैं Errorexpect(true).toBe(false);अगर आपका अनुमान Errorनहीं फेंका जाएगा तो आपके परीक्षण को विफल करने के लिए अजीब बात की आवश्यकता है । अन्यथा, यह रेखा कभी भी उपलब्ध नहीं है ( Errorउन्हें उनके सामने उठाया जाना चाहिए)।

संपादित करें: @ केनी बॉडी एक बेहतर समाधान सुझाती है जो यदि आप उपयोग करते हैं तो कोड की गुणवत्ता में सुधार करते हैं expect.assertions()

it('should throw Error with message \'UNKNOWN ERROR\' when no params were passed', () => {
  expect.assertions(1);
  try {
      throwError();
  } catch (e) {
      expect(e.message).toBe("UNKNOWN ERROR");
  }
});

अधिक स्पष्टीकरण के साथ मूल उत्तर देखें: जेस्ट में फेंके गए अपवाद के प्रकार का परीक्षण कैसे करें


18
इस अपवाद के लिए परीक्षण का एक बहुत ही वर्बोज़ तरीका है जब जेस्ट पहले से ही अपवाद के लिए जाँच की expect.toThrow () तरीका है: jestjs.io/docs/en/expect.html#tothrowerror
gomisha

4
हां, लेकिन यह केवल प्रकार का परीक्षण करता है, संदेश या अन्य सामग्री का नहीं और सवाल परीक्षण संदेश का था, प्रकार का नहीं।
bodolsog

2
हा। वास्तव में यह एक जैसा है क्योंकि मेरे कोड को फेंकी गई त्रुटि के मूल्य का परीक्षण करने की आवश्यकता है, इसलिए मुझे उदाहरण की आवश्यकता है। मैं दोषपूर्ण अपेक्षा को लिखूंगा जैसे expect('here').not.toBe('here');कि यह मज़े के लिए :-) :-)
Valery

4
@ माला या: expect('to be').not.toBe('to be')शेक्सपियर शैली में।
मिचेल वैन डेर ब्लोंक


41

मैं थोड़ा अधिक संक्षिप्त संस्करण का उपयोग करता हूं:

expect(() => {
  //code block that should throw error
}).toThrow(TypeError) //or .toThrow('expectedErrorMessage')

2
छोटा और सटीक।
मालपुआ

33

जेस्ट में मेरे (सीमित सीमित) एक्सपोजर से, मैंने पाया है कि expect().toThrow()यदि आप केवल एक विशिष्ट प्रकार की त्रुटि का परीक्षण करना चाहते हैं तो उपयुक्त है:

expect(() => functionUnderTest()).toThrow(TypeError);

या एक त्रुटि एक विशिष्ट संदेश के साथ फेंक दी जाती है:

expect(() => functionUnderTest()).toThrow('Something bad happened!');

यदि आप दोनों करने की कोशिश करते हैं, तो आपको एक झूठी सकारात्मक मिलेगी। उदाहरण के लिए यदि आपका कोड फेंकता है RangeError('Something bad happened!'), तो यह परीक्षा पास होगी:

expect(() => functionUnderTest()).toThrow(new TypeError('Something bad happened!'));

बॉडोलसोग का उत्तर जो एक कोशिश / कैच का उपयोग करने का सुझाव देता है, करीब है, लेकिन पकड़ने में आशाओं को सुनिश्चित करने के लिए झूठे होने की अपेक्षा करने के लिए सही होने की अपेक्षा, आप expect.assertions(2)अपने परीक्षण की शुरुआत में उपयोग कर सकते हैं , जहां 2अपेक्षित आशाओं की संख्या है । मुझे लगता है कि यह परीक्षण के इरादे का सटीक वर्णन करता है।

त्रुटि के प्रकार और संदेश के परीक्षण का पूर्ण उदाहरण:

describe('functionUnderTest', () => {
    it('should throw a specific type of error.', () => {
        expect.assertions(2);

        try {
            functionUnderTest();
        } catch (error) {
            expect(error).toBeInstanceOf(TypeError);
            expect(error).toHaveProperty('message', 'Something bad happened!');
        }
    }); 
});

यदि functionUnderTest()कोई त्रुटि नहीं करता है, तो दावे पर प्रहार किया जाएगा लेकिन वह expect.assertions(2)विफल हो जाएगा और परीक्षण विफल हो जाएगा।


डी 'ओह। मैं हमेशा जेस्ट की कई मुखरता की उम्मीद के बारे में भूल जाता हूं (संभवतः मैं व्यक्तिगत रूप से इसे सबसे अधिक सहज नहीं पाता, लेकिन यह निश्चित रूप से ऐसे मामलों के लिए काम करता है!) चीयर्स।
कोपलॉक

यह मेरे लिए पूरी तरह से ठीक है। इसका उपयोग किया जाना चाहिए।
अंकित तन्ना

expect.hasAssertions()बेहतर विकल्प तब हो सकता है जब परीक्षण में कोई जोर न हो catch, क्योंकि आपको अभिक्रियाओं को जोड़ने / हटाने के लिए संख्या को अपडेट नहीं करना है।
आंद्रे सस्सी

12

यह खुद करने की कोशिश नहीं की है, लेकिन मैं जेस्ट के सिद्धांत का उपयोग करने का सुझाव दूंगा । इसलिए मुझे लगता है कि आपका उदाहरण कुछ इस तरह दिखाई देगा:

it('should throw Error with message \'UNKNOWN ERROR\' when no params were passed', (t) => {
  const error = t.throws(() => {
    throwError();
  }, TypeError);

  expect(t).toThrowError('UNKNOWN ERROR');
  //or
  expect(t).toThrowError(TypeError);
});

फिर से, यह परीक्षण नहीं किया है, लेकिन मुझे लगता है कि यह काम करना चाहिए।


8

जेस्ट की एक विधि है toThrow(error) परीक्षण करने है कि एक फ़ंक्शन जब यह कहा जाता है तो फेंकता है।

तो, आपके मामले में आपको इसे कॉल करना चाहिए:

expect(t).toThrowError(TypeError);

डॉक्स


1
यह मामले के लिए काम नहीं करेगा: jest.spyOn(service, 'create').mockImplementation(() => { throw new Error(); });यदि नकली विधि createनहीं है async
सेर्गेई

7

आधुनिक जेस्ट आपको अस्वीकृत मूल्य पर अधिक जांच करने की अनुमति देता है। उदाहरण के लिए:

const request = Promise.reject({statusCode: 404})
await expect(request).rejects.toMatchObject({ statusCode: 500 });

त्रुटि के साथ विफल हो जाएगा

Error: expect(received).rejects.toMatchObject(expected)

- Expected
+ Received

  Object {
-   "statusCode": 500,
+   "statusCode": 404,
  }

6

यह कैसे करना है पर प्रलेखन स्पष्ट है। मान लीजिए कि मेरे पास एक फ़ंक्शन है जो दो मापदंडों को लेता है और अगर उनमें से एक है तो यह एक त्रुटि फेंक देगा null

function concatStr(str1, str2) {
  const isStr1 = str1 === null
  const isStr2 = str2 === null
  if(isStr1 || isStr2) {
    throw "Parameters can't be null"
  }
  ... // continue your code

आपका परीक्षण

describe("errors", () => {
  it("should error if any is null", () => {
    // notice that the expect has a function that returns the function under test
    expect(() => concatStr(null, "test")).toThrow()
  })
})


3

मैंने अपने परीक्षण-बर्तनों के पुस्तकालय के लिए एक सुविधा विधि लिखना समाप्त कर दिया

/**
 *  Utility method to test for a specific error class and message in Jest
 * @param {fn, expectedErrorClass, expectedErrorMessage }
 * @example   failTest({
      fn: () => {
        return new MyObject({
          param: 'stuff'
        })
      },
      expectedErrorClass: MyError,
      expectedErrorMessage: 'stuff not yet implemented'
    })
 */
  failTest: ({ fn, expectedErrorClass, expectedErrorMessage }) => {
    try {
      fn()
      expect(true).toBeFalsy()
    } catch (err) {
      let isExpectedErr = err instanceof expectedErrorClass
      expect(isExpectedErr).toBeTruthy()
      expect(err.message).toBe(expectedErrorMessage)
    }
  }

जैश के अपने फीचर्स का इस्तेमाल करके भी ऐसा ही किया जा सकता है। यह कैसे किया जा सकता है, इसके लिए मेरा जवाब देखें - stackoverflow.com/a/58103698/3361387
केनी बॉडी

3

पीटर डेनिस के पद के आगे उनके समाधान के हिस्से पर जोर देना चाहता था, जिसमें "[गुजरना] एक कार्य को अपेक्षा (कार्य) में शामिल किया गया था।" (रिक्त या त्रुटि का प्रकार) "।

जेस्ट में, जब आप एक ऐसे मामले के लिए परीक्षण करते हैं, जहां एक त्रुटि को फेंक दिया जाना चाहिए, तो आपकी उम्मीद के भीतर () परीक्षण के तहत लपेटकर आपको काम करने के लिए एक अतिरिक्त तीर फ़ंक्शन रैपिंग परत प्रदान करने की आवश्यकता होती है। अर्थात

गलत (लेकिन अधिकांश लोगों का तार्किक दृष्टिकोण):

expect(functionUnderTesting();).toThrow(ErrorTypeOrErrorMessage);

सही:

expect(() => { functionUnderTesting(); }).toThrow(ErrorTypeOrErrorMessage);

यह बहुत अजीब है, लेकिन परीक्षण को सफलतापूर्वक चलाना चाहिए।


1

प्रयत्न
expect(t).rejects.toThrow()


4
क्यों try? कोशिश नहीं है - लेकिन जवाब। यदि यह उत्तर है तो कृपया विस्तृत रूप से बताएं। आप मौजूदा उत्तर में क्या जोड़ रहे हैं?
dWinder

7
मुझे लगता है कि @Razim कह रहा था कि आपको समाधान की कोशिश करनी चाहिए, एक कोशिश पकड़ने का उपयोग नहीं करना चाहिए।
टॉम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.