মোচা / চাই প্রত্যাশিত। থ্রো ত্রুটি ধরছে না


257

expect.to.throwআমার নোড.জেএস অ্যাপ্লিকেশনটির পরীক্ষার জন্য চাইকে কাজ করতে সমস্যা হচ্ছে । পরীক্ষা নিক্ষেপ করা ত্রুটিটি ব্যর্থ করে রাখে, তবে আমি যদি পরীক্ষার কেসটি চেষ্টা করে গুটিয়ে রাখি এবং ধরা পড়ে থাকা ত্রুটির উপর দৃsert়তা জানাই তবে এটি কার্যকর হয়।

না expect.to.throwমত আমি মনে করি এটি করা উচিত বা কিছু কাজ করে না?

it('should throw an error if you try to get an undefined property', function (done) {
  var params = { a: 'test', b: 'test', c: 'test' };
  var model = new TestModel(MOCK_REQUEST, params);

  // neither of these work
  expect(model.get('z')).to.throw('Property does not exist in model schema.');
  expect(model.get('z')).to.throw(new Error('Property does not exist in model schema.'));

  // this works
  try { 
    model.get('z'); 
  }
  catch(err) {
    expect(err).to.eql(new Error('Property does not exist in model schema.'));
  }

  done();
});

ব্যর্থতা:

19 passing (25ms)
  1 failing

  1) Model Base should throw an error if you try to get an undefined property:
     Error: Property does not exist in model schema.

উত্তর:


339

আপনি একটি ফাংশন পাস করতে হবে expect। এটার মত:

expect(model.get.bind(model, 'z')).to.throw('Property does not exist in model schema.');
expect(model.get.bind(model, 'z')).to.throw(new Error('Property does not exist in model schema.'));

আপনি যেভাবে এটি করছেন, আপনি কল expectকরার ফলাফলের দিকে যাচ্ছেন model.get('z')। তবে কিছু ফেলে দেওয়া হয়েছে কিনা তা পরীক্ষা করতে আপনাকে একটি ফাংশন পাস করতে হবে expect, যা expectনিজেই কল করবে। bindউপরে পদ্ধতি ব্যবহার একটি নতুন ফাংশন যা যখন ডাকব নামক সৃষ্টি model.getসঙ্গে thisমান সেট modelকরুন এবং প্রথম আর্গুমেন্ট সেট 'z'

একটি ভাল ব্যাখ্যা এখানেbind পাওয়া যাবে


আমি একটি ফাংশন পাস করেছি আমি না? modelউদাহরণস্বরূপ গেট নামক একটি ফাংশন রয়েছে যা আমি প্রত্যাশায় পাস / পাস করেছি।
doremi

না, আপনি আপনার মন্তব্য লেখার সময় আমি যে ব্যাখ্যাটি যুক্ত করেছি তা দেখুন।
লুই

47
নগদ টাকা। দস্তাবেজগুলি ( chaijs.com/api/bdd/#throw ) কেন এই বাঁধাইয়ের ব্যবহারটি প্রদর্শন করে না? সর্বাধিক সাধারণ টেস্টিং দৃশ্যের মতো মনে হচ্ছে to.throwকোনও ফাংশনের মধ্যে একটি নির্দিষ্ট শর্ত পরীক্ষা করা, যার জন্য সেই ফাংশনটিকে অবৈধ অবস্থা / যুক্তিযুক্ত কল করা প্রয়োজন। (এই বিষয়টির জন্য .... চইজস ডট কমের ডিপ লিঙ্কগুলি আসলে কেন ডাবলিংক করবেন না?)
এরিকসোক

যখন আপনি এমন কিছু প্যারামিটারগুলি পাস করেন যা নিক্ষেপ করা উচিত নয়, পরীক্ষাটি এখনও পাস হয়।
আলেকজান্দ্রোস স্পাইরোপল্লোস

6
নোট করুন এটি (সেপ্টেম্বর 2017 হিসাবে) অ্যাসিঙ্ক ফাংশনগুলির জন্য কাজ করবে না: github.com/chaijs/chai/issues/882#issuecomment-322131680 এবং সম্পর্কিত আলোচনা দেখুন।
ChrisV

175

যেমন এই উত্তরটি বলেছে , আপনি কেবল নিজের কোডটি এইরকম একটি বেনামি কার্যক্রমে আবদ্ধ করতে পারেন:

expect(function(){
    model.get('z');
}).to.throw('Property does not exist in model schema.');

7
এটি অ্যাসিক্রোনাস ফাংশন কলগুলির জন্য কাজ করছে না। ধরুন মডেল.জেট অ্যাসিঙ্ক যা প্রতিশ্রুতি ফেরায় returns তবে এটি একটি ত্রুটি ছুড়ে ফেলে। যদি আমি উপরোক্ত পদ্ধতির চেষ্টা করে দেখি তবে এটি "টাইমিং আউট" হওয়ায় মোচায় আমাদের "সম্পন্ন" অবহিত করতে হবে। একই সাথে, expect(function(){ model.get('z'); }).to.throw('Property does not exist in model schema.').notify(done); কোনও বিজ্ঞপ্তি পদ্ধতি না থাকায় আমি চেষ্টা করতে পারছি না ।
আনন্দ এন

@ অ্যানডএন যদি আমি আপনার সমস্যাটি বুঝতে পারি তবে এটিকে শোনায় আপনার ত্রুটিটি পরিচালনা করতে আপনার কোডটি পুনরায় চুল্লি করা দরকার। অ্যাসিঙ্ক ফাংশনে আনহ্যান্ডড ত্রুটিটিও কি আপনার আসল অ্যাপে সমস্যা হতে পারে?
twiz

2
আপনার উত্তরের জন্য ধন্যবাদ twiz। আমরা একটি সংহত পরিবেশে কাজ করছি, ব্যবহারের মডিউলটি ব্যতিক্রমগুলি ধরার যত্ন নেয়। সুতরাং, সমস্যাটি যখন আমরা ইউনিট পরীক্ষার কেসগুলি চালানোর চেষ্টা করি। পরিশেষে আমরা এটি কাজ করতে নীচের পদ্ধতির ব্যবহার করেছি catch (err) { expect(err).equal('Error message to be checked'); done(); }
আনন্দ এন

1
কল করার জন্য আপনি যখন thisফাংশনটির ভিতরে ব্যবহার করছেন তখন ব্যতীত ভাল সমাধান । তারপরে .bindসঠিক উপায়।
খরগোশের

@AnandN অ্যাসিক্রোনাস ফাংশন কল নিক্ষেপ করবে না , এটি এসকে প্রত্যাখ্যান করে । ভবিষ্যতের রেফারেন্সের জন্য, ছাই-হিসাবে-প্রতিশ্রুতি এটি বেশ সুন্দরভাবে পরিচালনা করে।
ব্যবহারকারী 5532169

85

এবং যদি আপনি ইতিমধ্যে ES6 / ES2015 ব্যবহার করছেন তবে আপনি একটি তীর ফাংশনও ব্যবহার করতে পারেন। এটি মূলত একটি সাধারণ বেনাম ফাংশন ব্যবহার করার মতো তবে খাটো।

expect(() => model.get('z')).to.throw('Property does not exist in model schema.');

এ নিয়ে সমস্যা হতে পারে কারণ তীর ফাংশনগুলি তাদের আশেপাশের সুযোগ নেয়this
এরিক হোডনস্কি

1
@ রিলেক হ্যাঁ, খুব সত্য। এটি তীর ফাংশনগুলির একটি বড় সুবিধাও হতে পারে। তীর ফাংশন 'উত্তরাধিকারী' thisসুযোগ তারা কোথায় তৈরি করা হয়েছে। প্রায়শই এই, একটি সুবিধা হতে পারে যেমন প্রয়োজনীয়তার এড়াতে bindতাদের ফাংশন ing thisম্যানুয়ালি অবজেক্ট।
স্টিজন ডি উইট

@ স্টিজান্ডেভিট এটি কোনও সুবিধা বা অসুবিধা নয়, এটি স্কোপ নিয়ন্ত্রণ এবং ইচ্ছাকৃত। এটি আসলে ব্যবহারের জন্য সিনট্যাক্স চিনির bindএবং সর্বদা thisপিতামাতার সুযোগের সাথে আবদ্ধ । মন্তব্যে আমার উদ্দেশ্যটি কেবল পাঠকরা একটি সম্ভাব্য গর্ত পড়ার বিষয়ে সচেতন ছিল তা নিশ্চিত করার জন্য।
এরিক হোডনস্কি

1
@ রিলেক হ্যাঁ আমি আপনার সাথে একমত এটি কোনও সুবিধার জন্য ব্যবহৃত হতে পারে এবং তীর ফাংশনটি ব্যবহারের জন্য এটি একটি ভাল কারণ হতে পারে।
স্টিজন ডি উইট

75

এই প্রশ্নের অনেকগুলি নকল রয়েছে, যা চায়ের দৃser়তা গ্রন্থাগারের উল্লেখ না করে এমন প্রশ্ন সহ। এখানে একত্রে সংগ্রহ করা বেসিকগুলি:

দৃ immediately়তার সাথে অবিলম্বে মূল্যায়ন পরিবর্তে ফাংশনটি কল করা উচিত।

assert.throws(x.y.z);      
   // FAIL.  x.y.z throws an exception, which immediately exits the
   // enclosing block, so assert.throw() not called.
assert.throws(()=>x.y.z);  
   // assert.throw() is called with a function, which only throws
   // when assert.throw executes the function.
assert.throws(function () { x.y.z });   
   // if you cannot use ES6 at work
function badReference() { x.y.z }; assert.throws(badReference);  
   // for the verbose
assert.throws(()=>model.get(z));  
   // the specific example given.
homegrownAssertThrows(model.get, z);
   //  a style common in Python, but not in JavaScript

যে কোনও দৃser় পাঠাগার ব্যবহার করে আপনি নির্দিষ্ট ত্রুটিগুলি পরীক্ষা করতে পারেন:

নোড

  assert.throws(() => x.y.z);
  assert.throws(() => x.y.z, ReferenceError);
  assert.throws(() => x.y.z, ReferenceError, /is not defined/);
  assert.throws(() => x.y.z, /is not defined/);
  assert.doesNotThrow(() => 42);
  assert.throws(() => x.y.z, Error);
  assert.throws(() => model.get.z, /Property does not exist in model schema./)

উচিত

  should.throws(() => x.y.z);
  should.throws(() => x.y.z, ReferenceError);
  should.throws(() => x.y.z, ReferenceError, /is not defined/);
  should.throws(() => x.y.z, /is not defined/);
  should.doesNotThrow(() => 42);
  should.throws(() => x.y.z, Error);
  should.throws(() => model.get.z, /Property does not exist in model schema./)

চই আশা

  expect(() => x.y.z).to.throw();
  expect(() => x.y.z).to.throw(ReferenceError);
  expect(() => x.y.z).to.throw(ReferenceError, /is not defined/);
  expect(() => x.y.z).to.throw(/is not defined/);
  expect(() => 42).not.to.throw();
  expect(() => x.y.z).to.throw(Error);
  expect(() => model.get.z).to.throw(/Property does not exist in model schema./);

আপনাকে অবশ্যই ব্যতিক্রমগুলি পরিচালনা করতে হবে যা পরীক্ষাটি 'পালাতে' পারে

it('should handle escaped errors', function () {
  try {
    expect(() => x.y.z).not.to.throw(RangeError);
  } catch (err) {
    expect(err).to.be.a(ReferenceError);
  }
});

এটি প্রথমে বিভ্রান্ত দেখতে পারে। বাইক চালানোর মতো, একবার ক্লিক করলে এটি চিরতরে 'ক্লিক' করে।


13

দস্তাবেজ থেকে উদাহরণ ...;)

কারণ আপনি thisপ্রসঙ্গে নির্ভর :

  • থ্রো দ্বারা ফাংশনটি আহ্বান করা হলে এটি হারিয়ে যায়
  • এটি কী হওয়ার কথা তা জানার কোনও উপায় নেই

আপনাকে এই বিকল্পগুলির মধ্যে একটি ব্যবহার করতে হবে:

  • অন্য ফাংশনের অভ্যন্তরীণ পদ্ধতি বা ফাংশন কলটি মোড়ানো
  • প্রসঙ্গে বাঁধুন

    // wrap the method or function call inside of another function
    expect(function () { cat.meow(); }).to.throw();  // Function expression
    expect(() => cat.meow()).to.throw();             // ES6 arrow function
    
    // bind the context
    expect(cat.meow.bind(cat)).to.throw();           // Bind

এইভাবে আমি এটিও করি। আমি দেখতে পেলাম যে ES6 বাস্তবায়ন এখন পর্যন্ত সবচেয়ে পঠনযোগ্য
রিফিট.মেলোন

1

অন্য একটি সম্ভাব্য বাস্তবায়ন চেয়ে .bind () সমাধান আরো কষ্টকর, কিন্তু এক পয়েন্ট যে আশা () করতে সাহায্য করে প্রয়োজন একটি ফাংশন যে একটি উপলব্ধ thisকভার্ড ফাংশন প্রেক্ষাপটে, আপনি একটি ব্যবহার করতে পারেন call(), যেমন,

expect(function() {model.get.call(model, 'z');}).to.throw('...');


0

আমি এর চারপাশে একটি দুর্দান্ত উপায় খুঁজে পেয়েছি:

// The test, BDD style
it ("unsupported site", () => {
    The.function(myFunc)
    .with.arguments({url:"https://www.ebay.com/"})
    .should.throw(/unsupported/);
});


// The function that does the magic: (lang:TypeScript)
export const The = {
    'function': (func:Function) => ({
        'with': ({
            'arguments': function (...args:any) {
                return () => func(...args);
            }
        })
    })
};

এটি আমার পাঠ্য সংস্করণে আরও বেশি পঠনযোগ্য:

it ("unsupported site", () => {
    const args = {url:"https://www.ebay.com/"}; //Arrange
    function check_unsupported_site() { myFunc(args) } //Act
    check_unsupported_site.should.throw(/unsupported/) //Assert
});
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.