Асинхронное тестирование с обетами с использованием библиотеки http.get в Node.js - PullRequest
3 голосов
/ 11 июня 2011

У меня тупое время пытался заставить базовый http-тест работать с обетами.

Я думаю, что я последовал примеру асинхронности из обетов http://vowsjs.org/#-writing-asynchronous-tests и заменил соответствующие вызовы, но я должен что-то упустить.

Тестовый код выглядит так:

var http = require('http'),
    vows = require('vows'),
    assert = require('assert');

vows.describe("homepage").addBatch({
  "Get the home page": {
    topic: function() {
      http.get({'host': "127.0.0.1", 'port': 5000, 'path': '/'}, this.callback);
    },
    'should respond with 200 OK': function(res) {
      assert.equal(res.statusCode, 200);
    }
  }
}).export(module);

Я получаю следующую ошибку при попытке запустить тест для этого:

/Users/<home_folder>/node_modules/vows/lib/vows.js:80
rrored', { type: 'promise', error: err.stack || err.message || JSON.stringify(
                                                                    ^
TypeError: Converting circular structure to JSON
    at Object.stringify (native)
    at EventEmitter.<anonymous> (/Users/<home_folder>/node_modules/vows/lib/vows.js:80:90)
    at EventEmitter.emit (events.js:64:17)
    at /Users/<home_folder>/node_modules/vows/lib/vows/context.js:31:52
    at ClientRequest.<anonymous> (/Users/<home_folder>/node_modules/vows/lib/vows/context.js:46:29)
    at ClientRequest.g (events.js:143:14)
    at ClientRequest.emit (events.js:64:17)
    at HTTPParser.onIncoming (http.js:1349:9)
    at HTTPParser.onHeadersComplete (http.js:108:31)
    at Socket.ondata (http.js:1226:22)

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

UPDATE:

Очевидно, что добавление аргумента ошибки к обратному вызову решает эту проблему благодаря помощи Алексис Селлиер (создатель обетов).

Но я понятия не имею, почему. При написании примера http lib самостоятельно аргумент об ошибке не требуется. Я не могу найти никаких документов в клятвах, чтобы указать, почему это необходимо, поэтому я немного растерялся.

Мой новый вопрос: почему аргумент ошибки требуется при использовании http lib в vows?

Ответы [ 2 ]

4 голосов
/ 16 июня 2011

После проверки исходного кода клятвы я думаю, что знаю почему.Обеты всегда гарантируют, что когда вы вызываете this.callback, первый аргумент получающей функции-получателя всегда является объектом ошибки.Обеты интерпретируют обратные вызовы по следующим правилам:

  1. Если первый аргумент вашего исходного обратного вызова является логическим, используйте его, чтобы определить, добавлять ли объект ошибки к полученному обратному вызову (например,path.exists(boolean) вместо этого выдаст callback(error, exists))

  2. Если первый аргумент является объектом, предположим, что это объект ошибки, и используйте его, чтобы определить, добавлять ли исходный обратный вызов к ошибке ""или" список успеха ".Причина того, что этот список существует, заключается в поддержке тестов на основе обещаний, я думаю?

Хотя я не могу подтвердить, что вышеприведенное верно, мой опыт заключается в том, что асинхронный стиль vows сделан для поддержки узлабудет сложно проверить обратные вызовы (например, err как первый аргумент) и сторонние модули npm, которые не соответствуют этому стандарту.

Пожалуйста, не принимайте мой ответ как евангелие, так как этомой собственный опыт.Другая проблема - когда у вас есть асинхронные операции внутри функции, которую вы хотите протестировать - если вы не предоставите обратный вызов, обеты не смогут обработать это должным образом.

Лично я думаю, что обеты все еще затрудняютпроверить асинхронный код.Хотелось бы, чтобы у него было несколько функций управления потоком waitFor() или until().

Мое предложение?При работе с асинхронным кодом используйте Step .Не позволяйте обетам контролировать ваш поток.

1 голос
/ 10 августа 2011

Это фактически отсутствует в документации, которая все еще немного коротка.Но вы можете получить представление об этом здесь на этой странице :

'when peeled *asynchronously*': {
        topic: function (banana) {
            banana.peel(this.callback);
        },
        'results in a `PeeledBanana`': function (err, result) {
            assert.instanceOf (result, PeeledBanana);
        }
    }

Как было сказано Мортеном Зибуром и Рубеном Таном, именно так работают обеты и именно поэтому они работаютвот так.

...