【问题标题】:Node function returning 'undefined' before request completes with desired return value在请求完成之前返回“未定义”的节点函数并具有所需的返回值
【发布时间】:2016-03-12 03:37:01
【问题描述】:

我知道 Node 是关于回调的。当我了解有关 Jasmine 和 Node 的更多信息时,我在创建 Jasmine 测试时试图牢记这一点。

我使用 jasmine-node 编写了一个非常基本的测试,它应该获取一个 HTML 页面,使用 'cheerio' 加载和解析返回的 HTML,并提取 HTML 元素的内容。我的测试应该验证 'cheerio' 返回的文本的准确性。

我发现我正在测试的函数在请求完成之前返回“未定义”。您可以在测试的输出中看到这一点。在测试报告失败后,您会看到 console.log 输出。

我尝试使用回调来解决这个问题,并且我看到了有关使用诸如“异步”之类的库的帖子。我尝试使用 beforeEach() 来存储这些数据以供测试。

我没有找到正确的食谱,我需要一些帮助。

index.html

<!doctype html>
<html>
<body>
<span class="title">Title Goes Here</span>
</body>
</html>

module1.js

var request = require('request');
var cheerio = require('cheerio');

exports.whoAmI = function () {
    'use strict';
    return "module1";
};

exports.testJq = function () {
    'use strict';
    var tipsotext = function (callback) {
        var output;
        request.get('http://localhost/test-test/index.html', function optionalCallback(err, httpResponse, body) {
            var $ = cheerio.load(body);
            output = $('.title').text();
            console.log("Executing callback with data: " + output);
            callback(null, output);
        });
    };

    tipsotext(function (err, data) {
        console.log("Returning with data: " + data);
        return data;
    });
};

module1-spec.js(我的测试)

var module1 = require("../src/module1.js");

describe("module1", function () {
    'use strict';

    it("should identify itself with whoAmI", function () {
        var test;
        test = module1.whoAmI();
        expect(test).toBe("module1");
    });
    it("should get data from the page", function () {
        var test;
        test = module1.testJq();
        expect(test).toBe("Title Goes Here");
    });
});

我失败的测试的输出

Failures:

  1) module1 should get data from the page
   Message:
     Expected undefined to be 'Title Goes Here'.
   Stacktrace:
     Error: Expected undefined to be 'Title Goes Here'.
    at null.<anonymous> (c:\test-test\spec\module1-spec.js:14:22)

Finished in 0.011 seconds
2 tests, 2 assertions, 1 failure, 0 skipped

Executing callback with data: Title Goes Here
Returning with data: Title Goes Here

【问题讨论】:

    标签: javascript node.js jasmine jasmine-node


    【解决方案1】:
      tipsotext(function (err, data) {
        console.log("Returning with data: " + data);
        return data;
    });
    

    这个函数将数据返回给他的匿名函数 => function(err,data),因为这个方法是异步的,我认为你应该重新设计你的测试以支持异步方法并向 testJq 函数添加一个回调参数。

    【讨论】:

      【解决方案2】:

      重构,现在似乎可以工作了

      我重新构建了我的模块和测试,以使它们至少通过测试。我不确定这是编写模块的最佳方式,但这是朝着正确方向迈出的一步,并演示了一种编写 Jasmine 测试以检查异步请求返回的值的方法。

      我的大部分更改都来自Test Asynchronous Methods Using the Jasmine runs() and waitFor() Methods

      我在这里做了很多新手动作吗?有没有建议解决问题的专业人士?

      module1.js

      var request = require('request');
      var cheerio = require('cheerio');
      var title;
      exports.whoAmI = function () {
          'use strict';
          return "module1";
      };
      
      exports.extractTitleFromBody = function (callback) {
          'use strict';
          request({
              url: 'http://localhost:63342/browserify-test/index.html', //URL to hit
              method: 'GET'
          }, function(error, response, body){
              if(error) {
                  title = error;
              } else {
                  var $ = cheerio.load(body);
                  title = $('.title').text();
              }
              if (typeof callback === "function") {
                  callback();
              }
          });
      };
      exports.getTitle = function () {
          'use strict';
          return title;
      };
      

      module1-spec.js

      var module1 = require("../src/module1.js");
      
      describe("module1", function () {
          'use strict';
      
          it("should identify itself with whoAmI", function () {
              var me;
              me = module1.whoAmI();
              expect(me).toBe("module1");
          });
      
          it("should make a real AJAX request and return the title", function () {
              var callback = jasmine.createSpy("spy");
      
              module1.extractTitleFromBody(callback);
      
              waitsFor(function() {
                  return callback.callCount > 0;
              }, "The request timed out.", 5000);
      
              runs(function() {
                  expect(callback).toHaveBeenCalled();
              });
      
              runs(function() {
                  expect( module1.getTitle()).toBe("Title Goes Here");
              });
          });
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-02
        • 1970-01-01
        相关资源
        最近更新 更多