简体   繁体   English

如何使用内部调用返回promise的函数的茉莉花节点测试函数?

[英]How to test a function using jasmine-node which internally calls a function which returns a promise?

I am just trying out jasmine-node. 我只是尝试茉莉花节点。 I need some help with promise resolution. 我需要一些有关诺言解决的帮助。 I have simple js file 我有简单的js文件

//dataService.js

var Q = require('q');
console.info("Q is "+Q);
exports.test = function() {
    console.warn("Will call promise now");
    this.getQuestions().then(function() {
        console.log("Test..");
    });
};

exports.getQuestions = function() {

    var deferred = Q.defer();
    for(i=0; i<=10; i++) {
        if(i===10) {
            deferred.resolve(i);
        }
    }
    return deferred.promise;
    // return {
    //  'Question1': 'What is your name'
    // }
}

//end of dataService.js



And the test is

// testspec.js


var assert = require("assert");
var q = require('q');
var testFile = require('../routes/dataService');
var fs = require('fs');


  describe('#indexOf()', function(done){
    it('should return -1 when the value is not present', function(done){
        console.log("Teststststst" + fs);
      assert.equal(-1, [1,2,3].indexOf(5));
      assert.equal(-1, [1,2,3].indexOf(0));
      spyOn(testFile, 'getQuestions').andCallFake(function() {
            console.warn("Spy Called********************");
            var deferred = q.defer();
            deferred.resolve(1);
            console.info("passing 1****");  
            //done(1);
            return deferred.promise;
      });
      spyOn(console, 'log');
      testFile.test();
      console.info("Testststststsinggggggggg");
      expect(console.log).toHaveBeenCalledWith("Test..");
      console.info("Done*****************");
    })
  });

//end of test file //测试文件结束

Now as you can see I am calling testFile.test() function which is nothing but the test function in dataService.js. 现在,您可以看到我正在调用testFile.test()函数,它只是dataService.js中的测试函数。 This function calls the getQuestions() in the dataService.js (same file), which returns a promise. 此函数在dataService.js(相同文件)中调用getQuestions(),该函数返回一个Promise。 I have mocked the getQuestions() function in my test, it is getting called and is resolving the promise, but my test() success method is not getting called, so my test is failing. 我在测试中嘲笑了getQuestions()函数,该函数被调用并正在解决诺言,但是我的test()成功方法没有被调用,因此我的测试失败了。

Your getQuestions method never resolves the promise. 您的getQuestions方法永远无法解决承诺。

You have a loop running from 0 to 9 but you only resolve it if i === 10 . 您有一个从09的循环,但只有在i === 10才能解决。

Change: 更改:

for(i=0; i<10; i++) {
    if(i===10) {
        deferred.resolve(i);
    }
}

To: 至:

deferred.resolve(10);

As a general tip methods that call functions that return promises should return promises themselves so you can easly test them and hook on their completion. 作为一个一般性的技巧,调用返回promise的函数的方法应该自己返回promise,这样您就可以轻松地测试它们并挂钩其完成。 For this reason I'd make .test return a promise (rather than just call it) 因此,我会让.test返回一个.test (而不是仅仅调用它)

I was able to run the test by returning a promise from the test() function.


//dataService.js

var Q = require('q');
console.info("Q is "+Q);
exports.test = function() {
    console.warn("Will call promise now");
    return this.getQuestions().then(function() {
        console.log("Test..");
        return 'success';
    });

};

exports.getQuestions = function() {

    var deferred = Q.defer();
    for(i=0; i<10; i++) {
        if(i===3) {
            deferred.resolve(i);
        }
    }
    return deferred.promise;
    // return {
    //  'Question1': 'What is your name'
    // }
}

//end of dataService.js



//dataServicespec.js

var assert = require("assert");
var q = require('q');
var testFile = require('../routes/dataService');//include the dataService.js
var fs = require('fs');


describe('Tests', function(done) {
  it('should run the test properly', function(done) {
    console.log("Teststststst" + fs);
    var flag = false;
    var deferred;

    spyOn(testFile, 'getQuestions').andCallFake(function() {
      console.warn("Spy Called********************");
      deferred = q.defer();
      console.info("passing 1****");
      deferred.resolve(1);
      return deferred.promise;
    });

    spyOn(console, 'log');

    runs(function() {
      var p = testFile.test();
      p.then(function() {
        flag = true;
      });
    });

    waitsFor(function() {
      if (flag === true)
        return true;
    });

    runs(function() {
      console.info("Testststststsinggggggggg");
      expect(console.log).toHaveBeenCalledWith("Test..");
      console.info("Done*****************");
      done();
    });



  })
});

//end of dataServicespec.js


Thanx @Benjamin on you suggestion for returning a promise from test.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM