2012-04-30 1 views
0

Я новичок в стиле продолжения прохождения асинхронного вычисления, используемого в приложениях Node.js, и я изо всех сил пытаюсь понять какой-то довольно простой код.Обет тестирования обратного вызова в Node.js, генерирующий анонимные ошибки

Я пытаюсь написать библиотеку, которая создаст imap-интерфейс для imap.gmail.com, и я пытаюсь следовать BDD с помощью «vows'.js» (с разными уровнями успеха. следуя полному красному -> коду -> зеленому циклу, которым я должен быть, но на начальном этапе это трудно начать).

Соответствующий тест выглядит следующим образом:

var gmail = require('../lib/gmail.js'), 
    vows = require('vows'), 
    assert = require('assert'), 
    fs = require('fs'); 

vows.describe('Basic interface tests').addBatch({ 
    'A GMailInterface object can': { 
    topic: function() { 
     var gm = Object.create(gmail.GMailInterface); 
     var settings_file = 'test/test_settings.json'; 
     var settings = JSON.parse(fs.readFileSync(settings_file)); 
     var that = this; 
     gm.connect(settings.email,settings.password,function() { 
     that.callback(gm); // ERROR BEING GENERATED HERE 
     }); 
    }, 
    // ACTUAL VOWS OMITTED - the following is just a test of the callback 
    'find an email' : { 
     topic: function(gm) { 
     console.log(">>>",gm); 
     }, 
    } 
    } 
}).export(module) 

Если я пишу console.log сообщение прямо над линией с «ОШИБКА СРЕДСТВО СГЕНЕРИРОВАННЫМИ ЗДЕСЬ», он будет печатать. Это не будет, если я поставлю сообщение под ним. Выход теста дает следующее сообщение об ошибке:

node.js:201 
     throw e; // process.nextTick error, or 'error' event on first tick 
      ^
Error: Uncaught, unspecified 'error' event. 
    at EventEmitter.<anonymous> (events.js:50:15) 
    at EventEmitter.emit (/Users/eblume/Repositories/my_stuff/gmail/node_modules/vows/lib/vows.js:236:24) 
    at /Users/eblume/Repositories/my_stuff/gmail/node_modules/vows/lib/vows/context.js:31:52 
    at Object.callback (/Users/eblume/Repositories/my_stuff/gmail/node_modules/vows/lib/vows/context.js:46:29) 
    at Array.0 (/Users/eblume/Repositories/my_stuff/gmail/test/gmail_test.js:17:14) 
    at EventEmitter._tickCallback (node.js:192:40) 

код в gmail.js является немного слишком много, чтобы разместить здесь, но вот что я думаю, соответствующий раздел - я могу разместить больше, если вы спросите вопрос ниже.

gm.connect = function(username,password,cb) { 
    var self = this; 
    self.conn = new ImapConnection({ 
    username: username, 
    password: password, 
    host: 'imap.gmail.com', 
    port: 993, 
    secure: true 
    }); 

    async.series([ 
    function(callback){self.conn.connect(callback); }, 
    function(callback){self.conn.openBox('[Gmail]/All Mail',true,callback);} 
    ], 
    function(err,results) { 
    if (err) { 
     die(err); 
    } 
    process.nextTick(cb); 
    }); 
}; 

Где я могу ошибиться? Спасибо за любую помощь!

+0

Будущим людям с аналогичными проблемами - я просто переключился на «мокко», что, на мой взгляд, намного лучше, чем BDD. Это дало мне гораздо более краткими и легко понятными ошибки, и вскоре я исправил свою проблему (которая фактически была циклом событий ожидания в соединении, запущенном в другой функции.) – eblume

ответ

1

Я рекомендую прочитать, как это работает. Если никто не возился с ним, то «то» that.callback относится к родительскому объекту, который помечен литеральной строкой как «объект GMailInterface».

Я подозреваю, что этот фактор отключает вас. «обратный вызов» должен быть определен как метод того же объекта, что и метод «тема», как у вас есть вещи, которые меня не устраивают, так как он предназначен для работы.

'this' обычно относится к ближайшему предку/родительскому объекту по умолчанию. Он игнорирует функции упаковки, если они не используются как конструкторы, использующие ключевое слово 'new', и в этом случае он указывает экземпляр объекта. В случае обратных вызовов событий в DOM (браузер JS - not node.js, который я не знаю подробно в отношении событий), он обычно относится к объекту, на котором было инициировано событие.

Не существует настоящего храма с этим и самим собой. Мы просто стараемся использовать их, чтобы быть уверенными, что мы обращаемся к верхнему объекту в случаях, когда объект имеет совокупные объекты.

+0

Спасибо за подсказку - и вы абсолютно правы что мне нужно более тщательно изучить привязку «этого». Однако, основываясь на [vows documentation] (http://vowsjs.org/) (проверьте последний пример в самой темной части по направлению к вершине - то, что происходит с асинхронным очищением бананов), похоже, что «это» становится привязанным к то, что на самом деле имеет метод «обратного вызова» по «обетам». Это подтверждается заменой 'gm' в args' callback' для чего-то еще, такого как 'true', который печатает« >>> true »на консоли, а затем зависает бесконечно. – eblume

+0

Хорошо, ну, в примерах я вижу использование нового ключевого слова для предмета, которому присваивается «тема». Это означает, что объект создается. тема, вероятно, попадает на событие, на которое реагируют, поэтому вероятная цель этого. –

Смежные вопросы