আমি মোচা এবং চায়ের সাথে প্রতিশ্রুতিগুলি কীভাবে সঠিকভাবে পরীক্ষা করব?


148

নিম্নলিখিত পরীক্ষাটি অদ্ভুত আচরণ করছে:

it('Should return the exchange rates for btc_ltc', function(done) {
    var pair = 'btc_ltc';

    shapeshift.getRate(pair)
        .then(function(data){
            expect(data.pair).to.equal(pair);
            expect(data.rate).to.have.length(400);
            done();
        })
        .catch(function(err){
            //this should really be `.catch` for a failed request, but
            //instead it looks like chai is picking this up when a test fails
            done(err);
        })
});

আমি কীভাবে প্রত্যাখ্যাত প্রতিশ্রুতিটি সঠিকভাবে পরিচালনা করব (এবং এটি পরীক্ষা করব)?

আমি কিভাবে সঠিকভাবে একটি ব্যর্থ পরীক্ষা হ্যান্ডেল করা হয় (যেমন: expect(data.rate).to.have.length(400);?

এখানে আমি বাস্তবায়ন করছি যা পরীক্ষা করছি:

var requestp = require('request-promise');
var shapeshift = module.exports = {};
var url = 'http://shapeshift.io';

shapeshift.getRate = function(pair){
    return requestp({
        url: url + '/rate/' + pair,
        json: true
    });
};

উত্তর:


233

সবচেয়ে সহজ কাজটি হ'ল মোচা সাম্প্রতিক সংস্করণগুলিতে অন্তর্নির্মিত প্রতিশ্রুতিগুলিকে সমর্থন করে:

it('Should return the exchange rates for btc_ltc', function() { // no done
    var pair = 'btc_ltc';
    // note the return
    return shapeshift.getRate(pair).then(function(data){
        expect(data.pair).to.equal(pair);
        expect(data.rate).to.have.length(400);
    });// no catch, it'll figure it out since the promise is rejected
});

অথবা আধুনিক নোড এবং অ্যাসিঙ্কের সাথে / অপেক্ষা করুন:

it('Should return the exchange rates for btc_ltc', async () => { // no done
    const pair = 'btc_ltc';
    const data = await shapeshift.getRate(pair);
    expect(data.pair).to.equal(pair);
    expect(data.rate).to.have.length(400);
});

যেহেতু এই পদ্ধতির সমাপ্তি প্রতিশ্রুতিবদ্ধ তাই এটি পরীক্ষা করা আরও সহজ এবং আপনি যে অদ্ভুত ঘটনাগুলির বিষয়ে ভাবছেন তা আপনি done()সর্বত্র অদ্ভুত কলগুলির মতো ভাববেন না ।

এই মুহূর্তে জুসিনের মতো অন্যান্য লাইব্রেরিগুলির উপরে মোচার একটি সুবিধা। আপনি প্রতিশ্রুত হিসাবে চই চেক করতেও পারেন যা এটি আরও সহজ করে (না .then) তবে ব্যক্তিগতভাবে আমি বর্তমান সংস্করণের স্পষ্টতা এবং সরলতাকে পছন্দ করি


4
মোচার কোন সংস্করণে এটি শুরু হয়েছিল? Ensure the done() callback is being called in this testমোচা ২.২.৫ দিয়ে এটি করার চেষ্টা করার সময় আমি একটি ত্রুটি পেয়েছি ।
স্কট

14
@ স্কট যে কোনও doneপরামিতি গ্রহণ করবেন না itএটির থেকে এটি বেরিয়ে আসে।
বেনিয়ামিন গ্রুইনবাউম

2
এটি আমার পক্ষে খুব সহায়ক ছিল। doneআমার itকলব্যাকটি মুছে ফেলা , এবং কলব্যাকে স্পষ্টভাবে কল করা return(প্রতিশ্রুতিতে) কোড কোড স্নিপেটের মতো আমি কীভাবে এটি কাজ করে চলেছি তা হল।
জনি কোডার

5
দুর্দান্ত উত্তর, নিখুঁত কাজ করে। দস্তাবেজগুলির দিকে ফিরে তাকানো, এটি সেখানে রয়েছে - অনুমান করা খুব সহজ। Alternately, instead of using the done() callback, you may return a Promise. This is useful if the APIs you are testing return promises instead of taking callbacks:
ফেডেরিকো

4
স্কটের মতো একই সমস্যা হচ্ছে। আমি কলটিতে কোনও doneপরামিতি দিচ্ছি না it, এবং এটি এখনও চলছে ...

43

ইতিমধ্যে এখানে ইশারা করা হিসাবে , মোচা এর নতুন সংস্করণগুলি ইতিমধ্যে প্রতিশ্রুতি-সচেতন। তবে যেহেতু ওপি চায়ের বিষয়ে বিশেষভাবে জিজ্ঞাসা করেছে, তাই কেবলমাত্র সেই chai-as-promisedপ্যাকেজটি দেখানো ন্যায়সঙ্গত যা প্রতিশ্রুতিগুলির পরীক্ষার জন্য একটি পরিষ্কার সিনট্যাক্স সরবরাহ করে:

প্রতিশ্রুতি হিসাবে ছাই ব্যবহার

প্রতিশ্রুতি হিসাবে কেস resolveএবং rejectকেস উভয়ই পরীক্ষার জন্য ছাই-হিসাবে-প্রতিশ্রুতি ব্যবহার করতে পারেন তা এখানে :

var chai = require('chai');
var expect = chai.expect;
var chaiAsPromised = require("chai-as-promised");
chai.use(chaiAsPromised);

...

it('resolves as promised', function() {
    return expect(Promise.resolve('woof')).to.eventually.equal('woof');
});

it('rejects as promised', function() {
    return expect(Promise.reject('caw')).to.be.rejectedWith('caw');
});

প্রতিশ্রুতি ছাড়াই

কী পরীক্ষা হচ্ছে তা সত্যই পরিষ্কার করার জন্য, এখানে যেমন উদাহরণ দেওয়া হয়েছে তা ছাই-যেমন-প্রতিশ্রুতি ব্যতীত কোড করা হয়েছে:

it('resolves as promised', function() {
    return Promise.resolve("woof")
        .then(function(m) { expect(m).to.equal('woof'); })
        .catch(function(m) { throw new Error('was not supposed to fail'); })
            ;
});

it('rejects as promised', function() {
    return Promise.reject("caw")
        .then(function(m) { throw new Error('was not supposed to succeed'); })
        .catch(function(m) { expect(m).to.equal('caw'); })
            ;
});

5
দ্বিতীয় পদ্ধতির সমস্যাটি catchহ'ল অনুরোধ করা হয় যখন কোনও expect(s)ব্যর্থ হয়। এটি একটি ভুল ধারণা দেয় যা প্রতিশ্রুতি ব্যর্থ হলেও তা ব্যর্থ হয়েছিল। এটি কেবল প্রত্যাশা যে ব্যর্থ হয়েছিল।
TheCrazyProgrammer

2
পবিত্র হেক ধন্যবাদ আমাকে বলার জন্য Chai.useএটি মাউন্ট করার জন্য আমাকে ধন্যবাদ জানাতে হবে। তাদের যে ডকুমেন্টেশন ছিল তা থেকে আমি কখনই এটি তুলতে পারতাম না। | :(
আরসিমে

3

এখানে আমার গ্রহণ:

  • ব্যবহার async/await
  • অতিরিক্ত চাই মডিউলগুলির প্রয়োজন নেই
  • ক্যাচ ইস্যু এড়ানো, উপরের দিকে নির্দেশিত @ ক্র্যাজিপ্রোগ্রামার

একটি বিলম্বিত প্রতিশ্রুতি ফাংশন, এটি ব্যর্থ হয়, যদি 0: এর বিলম্ব দেওয়া হয়

const timeoutPromise = (time) => {
    return new Promise((resolve, reject) => {
        if (time === 0)
            reject({ 'message': 'invalid time 0' })
        setTimeout(() => resolve('done', time))
    })
}

//                     ↓ ↓ ↓
it('promise selftest', async () => {

    // positive test
    let r = await timeoutPromise(500)
    assert.equal(r, 'done')

    // negative test
    try {
        await timeoutPromise(0)
        // a failing assert here is a bad idea, since it would lead into the catch clause…
    } catch (err) {
        // optional, check for specific error (or error.type, error. message to contain …)
        assert.deepEqual(err, { 'message': 'invalid time 0' })
        return  // this is important
    }
    assert.isOk(false, 'timeOut must throw')
    log('last')
})

ইতিবাচক পরীক্ষা বরং সহজ। 500→0প্রত্যাশিত প্রতিশ্রুতি বাড়ার সাথে সাথে অপ্রত্যাশিত ব্যর্থতা (অনুকরণ ) পরীক্ষা স্বয়ংক্রিয়ভাবে ব্যর্থ হবে।

নেতিবাচক পরীক্ষা চেষ্টা-ধারণা ব্যবহার করে। তবে: অনাকাঙ্ক্ষিত পাস সম্পর্কে 'অভিযোগ করা' তখনই ক্যাচ ক্লজ (এইভাবে, এটি ক্যাচ ক্লজটিতে শেষ হয় না, আরও ট্রিগার করে তবে বিভ্রান্তিকর ত্রুটি হয়।

এই কৌশলটি কাজ করার জন্য, অবশ্যই ক্যাচ ক্লজ থেকে পরীক্ষাটি ফিরিয়ে দিতে হবে। আপনি যদি অন্য কোনও কিছুর পরীক্ষা করতে না চান তবে এটি ব্যবহার করুন () - ব্লক।


2

থ্রে একটি ভাল সমাধান। কেবল একটি ক্যাচ ব্লকে করে ত্রুটিটি ফিরিয়ে দিন।

// ...

it('fail', (done) => {
  // any async call that will return a Promise 
  ajaxJson({})
  .then((req) => {
    expect(1).to.equal(11); //this will throw a error
    done(); //this will resove the test if there is no error
  }).catch((e) => {
    done(e); //this will catch the thrown error
  }); 
});

এই পরীক্ষা নিম্নলিখিত বার্তার সাথে ব্যর্থ হবে: AssertionError: expected 1 to equal 11

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.