2015-06-06 10 views
6

मैं कोड का एक वर्ग है कि इतनी तरह node-sync उपयोग कर रहा है है:परीक्षण तुल्यकालिक कोड

function funcA() { 
    return new Promise(function(resolve, reject) { 
    Sync(function() { 
     return funcB.sync(); 
    }, function (err, result) { 
     if(err) { 
     reject(err); 
     } else { 
     resolve(result); 
     } 
    }); 
} 

इस कोड मोचा + चाय का उपयोग कर परीक्षण किया जाता है

it("should return array", function() { 
    return funcA().then(function(result) { 
    expect(result).to.be.an.instanceof(Array); 
    }); 
}); 

यह ठीक दो महीने के पहले काम किया , लेकिन अब यह परीक्षण हमेशा समय समाप्त होता है:

Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.

मैंने अब तक क्या प्रयास किया है:

  • बजाय done() का उपयोग कर एक वादा
  • synchronize.js
  • बढ़ती टाइमआउट साथ node-sync की जगह लौटने

क्या मुझे पता चला है कि इस परीक्षण के expect(... हिस्सा है, वास्तव में, कहा जाता है की जा रही है , लेकिन मोचा के बाद ही परीक्षण खत्म हो जाता है। इससे कोई फर्क नहीं पड़ता कि वर्तमान में टाइमआउट अंतराल सेट किया गया है, को Error: timeout संदेश मिलने के बाद हमेशा ~ 20 मिलीसेकंड कहा जा रहा है।

मैंने परीक्षण फ़ाइल के शीर्ष पर setInterval(function(){}, 10) जोड़कर समस्या को ठीक किया। मुझे यह जानना है कि यह क्यों काम करता है और अगर इसे ठीक करने का कोई बेहतर तरीका है?

[संपादित करें] ऐसा लगता है कि यह एक नोड-संस्करण विशिष्ट समस्या है। टेस्ट 0.12.4 पर विफल रहता है लेकिन 0.10.38 पर सही ढंग से चलता है।

[संपादित करें] वास्तविक कोड here उपलब्ध है।

+1

बहुत अजीब लगता है .. मैं इसे पुन: पेश कर सकता हूं लेकिन यह पता नहीं लगा सकता कि समस्या क्या है। एक लंबा शॉट हो सकता है लेकिन हो सकता है कि नोड-सिंक में खोदें, इन जिथब टिकटों को देखें [यहां] (https://github.com/ybogdanov/node-sync/issues/41) और [यहां] (https: // github। com/ybogdanov/node-sync/issues/36) –

+0

btw यह आमतौर पर परीक्षण में असीमित रूप से कोड चलाने के लिए सबसे अच्छा अभ्यास (imho) है। मुझे पता है कि आप इस ब्लॉक सिंक को चलाने का प्रयास कर रहे हैं, लेकिन शायद चाई-ए-वादा मॉड्यूल को आज़माएं ताकि आप 'done' –

उत्तर

1

तुम बस done() कॉलबैक गायब हो सकता है:

it("should return array", function(done) { 
    funcA().then(function(result) { 
     expect(result).to.be.an.instanceof(Array); 
     done(); 
    }); 
}); 

http://mochajs.org/#asynchronous-code

+0

हे को हटा सकें, सुझाव के लिए धन्यवाद - जैसा कि मैंने पहले ही कोशिश की है कि मैंने पहले से ही किया है। इसके अलावा, एक वादा वापस करना ठीक काम करना चाहिए (वास्तव में आप मोचा डॉक्स में बहुत से अनुभाग से जुड़े हुए हैं जहां यह वर्णित है)। मेरा मुद्दा नोड-संस्करण से संबंधित प्रतीत होता है। –

2

अपने code आधार पर, मैं अपने funcB समारोह एक तुल्यकालिक रास्ता में कोड चल रहा है यह सोचते हैं रहा हूँ।

तो जब मैं इस तरह से funcB बनाएँ:

function funcB() { 
    return [1, 2, 3]; 
} 

और परीक्षण चलाने, मोचा एक त्रुटि दिखाता है:

Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.

लेकिन अगर मैं asynchronus समारोह में funcB परिवर्तित इस रूप में :

function funcB(cb) { 
    process.nextTick(function() { 
    cb(null, [1, 2, 3]); 
    }); 
} 

मोचा बिना किसी समस्या के परीक्षण चलाता है:

✓ should return an array


तो मेरा पूरा कोड है कि ठीक चलाता है यह है (funcB टिप्पणी की है कि त्रुटि का कारण होगा):

// install dependencies 
// npm install promise 
// npm install sync 
var Promise = require('promise'); 
var assert = require('assert'); 
var Sync = require('sync'); 

function funcA() { 
    return new Promise(function (resolve, reject) { 
    Sync(function() { 
     return funcB.sync(); 
    }, function (err, result) { 
     if (err) { 
     reject(err); 
     } else { 
     resolve(result); 
     } 
    }); 
    }); 
} 

// function funcB() { 
// return [1, 2, 3]; 
// } 

function funcB(cb) { 
    process.nextTick(function() { 
    cb(null, [1, 2, 3]); 
    }); 
} 

it("should return an array", function(done) { 
    return funcA().then(
    function (result) { 
     console.log(result); 
     assert.equal(Array.isArray(result), true); 
     done(); 
    } 
); 
}); 

तो मैं कर रहा हूँ राय मुझे लगता है कि के दुरुपयोग लगता है सिंक लाइब्रेरी द्वारा बनाई गई sync method (सिंक्रोनस फ़ंक्शंस पर इसका उपयोग करके) वह समस्या है जो इस समस्या का कारण बन रही है।

+0

हे विल्सन! इसके लिए धन्यवाद, लेकिन यह अभी भी एक हैक है और यह जवाब नहीं देता है कि ऐसा क्यों होता है। मुझे लगता है कि 'setInterval' का उपयोग आपके' nextTick' हैक के समान सटीक उद्देश्य प्रदान करता है। ऐसा लगता है कि नोड "सो जाता है" और 'अगली टिक' या 'सेट इंटरवल' द्वारा जागृत होने की आवश्यकता है। सवाल यह है कि, ऐसा क्यों होता है और यदि यह कोई नोड समस्या है, तो सिंक समस्या या अपेक्षित व्यवहार? मुझे इसके निचले हिस्से तक जाना अच्छा लगेगा। –

+0

शायद मैं गलत हूं लेकिन [विधि] (https://github.com/ybogdanov/node-sync/blob/master/lib/sync.js#L27) के दस्तावेज़ से तर्क दे रहा हूं जो कहता है: * "सिंक() विधि बस सिंक्रोनस को किसी भी एसिंक्रोनस फ़ंक्शन को बदल देती है "* इसलिए इस विधि को funcB जैसे सिंक फ़ंक्शन से कॉल करना, मेरे लिए संभावित रूप से बग का स्रोत हो सकता है। – Wilson

1

आप मोचा निष्पादन योग्य के लिए टाइमआउट पैरामीटर का उपयोग कर सकते हैं।

उदाहरण के लिए, यदि आप एक 500 मिलीसेकंड समय समाप्त करना चाहते हैं, बस बदलने के अपने package.json रहे हैं:

"scripts": { 
    "test": "mocha specs --timeout 500 --require specs/helpers/chai.js" 
}, 

और शायद अपने वादे को अस्वीकार कर दिया जा रहा है, तो आप catch पद्धति का उपयोग करके done कॉल करनी होगी।

it("should return array", function(done) { 
    return funcA().then(function(result) { 
     expect(result).to.be.an.instanceof(Array); 
     done(); 
    }).catch(done); 
}); 

इससे आपको आपके वादे कोड में होने वाली अंतिम त्रुटियों को डीबग करने में भी मदद मिलेगी।

+0

हे! जैसा कि सवाल में बताया गया है, मैंने टाइमआउट बढ़ाने की कोशिश की है - टेस्ट विफल रहता है * हमेशा * टाइमआउट के ठीक बाद (कोई फर्क नहीं पड़ता कि टाइमआउट मान क्या है)। पकड़ना एक अच्छी टिप है, लेकिन यह परीक्षण विफल नहीं होता है, यह समय समाप्त हो जाता है। –

+0

@ कोनराडडज़विन हम्म .. ऐसा लगता है कि आप ऐसे कोडों का परीक्षण करने की कोशिश कर रहे हैं जो एक ही प्रक्रिया में सबकुछ करते हैं। 'SetTimeout()' to process.nextTick(); 'को बदलने का प्रयास करें; और जांचें कि यह अभी भी काम करता है या नहीं।साथ ही, क्या आप जिस विधि का परीक्षण करने का प्रयास कर रहे हैं उसका कोड भेज सकते हैं? – Tulio

+0

हे! पूरी चीज उपलब्ध है [यहां] (https://github.com/kdzwinel/Proofreader)। टेस्ट नोड 0.10 पर गुजरते हैं लेकिन 0.12 पर असफल होते हैं। मैं बाद में क्लिक करने के लिए setInterval बदलने की कोशिश करेंगे। मेरा अनुमान है कि यह काम करेगा - सवाल यह है कि मुझे अगले टिक मैन्युअल रूप से नोड 0.12 में ट्रिगर करना है? –

संबंधित मुद्दे