Тестирование обратных вызовов Vows в Node.js, генерирующее анонимные ошибки

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

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

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

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);
  });
};

Куда я могу пойти не так? Спасибо за любую помощь!

1 ответ

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

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

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

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

Другие вопросы по тегам