简体   繁体   中英

testing node.js using mocha and promises

I am building an API that uses CouchDB as a backend and whilst building the backend library I want to create a function in a library to add a user account and return success or failure but the callbacks are causing problems.

After reading up on JS Promises I realised that these would solve my problems but I can't get them to work despite reading lots of tutorials.

Could you take a look at my code and help me understand why it won't work?

var request = require('request');
var md5 = require('MD5');
var crypto = require('crypto');
var Q = require('q');

exports.new_account = function(params) {
    console.log("\nNEW_ACCOUNT")
    params.password = md5(params.password);
    //console.log(params);
    var token = crypto.randomBytes(16).toString('hex');
    var record = {
        type:"user", 
        status:"pending", 
        token:token, 
        credentials:params
    };
    console.log(record);

    var uri = 'http://127.0.0.1:5984/testdb/'+params.email;
    var deferred = Q.defer();
    request({method: 'PUT', uri:uri, body: JSON.stringify(record)}, function (error, response, body) {
        console.log('performing request')
        var top = JSON.parse(body);
        console.log(top);
        if (top.error == 'conflict') {
            console.log('the supplied email address already exists');
            deferred.reject('account exists!');
        }
        console.log('resolving request')
        deferred.resolve('account added.');
    })
    //var res = {status:"success", message:"Account created"};
    return deferred.promise;
}

Thanks,

First of all I think the callback function of your request should look like this:

function (error, response, body) {
  console.log('performing request');
  var top = JSON.parse(body);
  console.log(top);
  if (top.error == 'conflict') {
    console.log('the supplied email address already exists');
    deferred.reject('account exists!');
  } else {
    console.log('resolving request');
    deferred.resolve('account added.');
  }
})

That's because you can't call both resolve and reject . If top.error == 'conflict' this will be the case.

How do you use the return value of this function?

For testing you can use mocha with chai and chai-as-promised . Your test could look like this (with chai and chai-as-promised which are very helpfull):

var chai = require('chai'),
    chaiAsPromised = require("chai-as-promised"),
    assert;

chai.use(chaiAsPromised);
assert = chai.assert;

describe('user', function () {
  describe('.new_account', function () {
    afterEach(function (done) {
      done();
    });

    it("status should be success", function () {
      var params = {name: "John Doe", email: "test@gmail.com", password: "p455w0rd"};
      var promise = user.new_account(params);
      var expectedResult = 'account added.';

      //the first time, the account should be created successfully.
      return assert.becomes(promise, expectedResult, 'account added.');
    });
  });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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