Как я могу ожидать, что функция будет вызываться с определенными аргументами с sinon, mocha и chai в nodejs?

У меня возникла проблема, пытаясь убедиться, что Q.ninvoke вызывается с аргументами, которые я передаю. Я новичок в тестировании с Sinon, Mocha и Chai. Я пробовал все, что нашел в Интернете, уже 2 дня, и я до сих пор не могу пройти тест. Что я делаю не так?

Это мой тестируемый код.

var cuid = require('cuid');
var fs = require('fs');
var Q = require('q');
var AWS = require('aws-sdk');
var S3 = new AWS.S3();

module.exports = {
  initialize: initialize
};

function initialize(options) {
  return Q.nfcall(fs.readFile, options.path).then(function (file) {
    var fileParams = {
      Bucket: options.bucket,
      Key: options.name,
      Body: file,
      ContentType: options.contentType
    };

    return Q.ninvoke(S3, 'upload', fileParams).then(function(data){
      return data.Location;
    });
  });
}

Вот мой тест.

describe.only('when a file is read successfully', function() {
    var spy;

    beforeEach(function() {
        spy = chai.spy.on(Q, 'ninvoke');
        sinon.stub(Q, 'nfcall').withArgs(fs.readFile, fileParams.path).returns(Q.resolve(file));
    });

    it('Q.ninvoke should be called with args', function() {
        UploadCommand.initialize(fileParams)
        expect(spy).to.have.been.called.with(S3, 'upload', params);
    });
});

Это ошибка, которую я получаю.

1) UploadCommand .initialize при успешном чтении файла Q.ninvoke следует вызывать с аргументами: AssertionError: ожидается, что {Spy} будет вызван с [Array(3)]


person Logan Fisher    schedule 12.12.2015    source источник


Ответы (3)


попробуй это:

var cuid = require('cuid');
var fs = require('fs');
var Q = require('q');
var AWS = require('aws-sdk');
var S3 = new AWS.S3();

module.exports = {
  initialize: initialize
};

function initialize(options) {
   return Q.nfcall(fs.readFile, options.path).then(function (file) {
    var fileParams = {
       Bucket: options.bucket,
       Key: options.name,
       Body: file,
       ContentType: options.contentType
    };

    return Q.ninvoke(S3, 'upload', fileParams);
  });
}

обратите внимание, в частности, что вы должны вернуть обещание из вашей функции инициализации. то в тесте:

describe.only('when a file is read successfully', function() {
      var spy;

      beforeEach(function() {
      spy = chai.spy.on(Q, 'ninvoke');
      sinon.stub(Q, 'nfcall').withArgs(fs.readFile,fileParams.path).returns(Q.resolve(file));
   });

  it('Q.ninvoke should be called with args', function(done) {
    UploadCommand.initialize(fileParams).then(function(data) {
       expect(spy).to.have.been.called.with(S3, 'upload', params);
       done();
    });
  });
});

еще несколько моментов, на которые следует обратить внимание: в основном коде приложения вы также захотите связать свою функцию инициализации с функцией «тогда», а в теле этой функции «тогда» должен находиться остальной код вашего приложения. Кроме того, обратный вызов «done» — это способ сообщить мокко, что это асинхронный тест.

person Mike Atkins    schedule 12.12.2015
comment
взгляните на mochajs.org в разделе о работе с промисами вместо использования "done". - person Mike Atkins; 13.12.2015
comment
Похоже, я приближаюсь, большое спасибо, чувак. Теперь я получаю эту ошибку. Ошибка: превышено время ожидания 2000 мс. Убедитесь, что обратный вызов done() вызывается в этом тесте. - person Logan Fisher; 13.12.2015
comment
этот бит неверен: Q.resolve (файл). возможно, попробуйте Q.defer().resolve() - person Mike Atkins; 13.12.2015
comment
Майк, благодаря тебе я наконец смог заставить его работать. Я очень ценю это! Вот и последний тест. - person Logan Fisher; 14.12.2015

Майк, благодаря тебе я наконец смог заставить его работать. Я очень ценю это! Вот и последний тест.

describe.only('when a file is read successfully', function() {
  beforeEach(function() {
    sinon.stub(Q, 'nfcall').withArgs(fs.readFile, fileParams.path).returns(Q.resolve(file));
    sinon.stub(Q, 'ninvoke').withArgs(S3, 'upload', params).returns(Q.resolve('url'));
    chai.spy.on(Q, 'ninvoke')
  });

  it('Q.ninvoke should be called with args', function(done) {
    UploadCommand.initialize(fileParams).then(function(data) {
       expect(Q.ninvoke).to.have.been.called.with(S3, 'upload', params);
       done();
    });
  });
});
person Logan Fisher    schedule 13.12.2015

Вы можете использовать sinon для заглушки, как показано ниже.

let yourFunctionStub
yourFunctionStub= sinon.stub(yourClass, "yourFunction");
                    yourFunctionStub.withArgs(arg1, arg2, arg3).returns(resultYouWant);

если это обещание, вы можете вернуться

....returns(Promise.resolve(resultYouWant));

если для аргумента вы не ясно, вы можете

sinon.match.any

Надеюсь, это поможет вам. :)

person Nikit Prabhu    schedule 23.08.2017
comment
Что конкретно добавляет этот ответ, что а) не был охвачен более ранними ответами, уже опубликованными за несколько лет до вашего, и б) является проблемой, поднятой вопросом, который задал ОП? - person Louis; 23.08.2017