如何使用间谍在测试工厂中使用间谍?

时间:2015-10-11 02:33:21

标签: node.js testing promise mocha chai

我想测试一下这段代码:

'use strict';

var Promise = require('bluebird');
var AWS = require('aws-sdk');
var fs = Promise.promisifyAll(require('fs-extra'));
var path = require('path');

var dispatcher = function() {
  return {
    /**
     * @param {Object} options
     * @param {string} options.s3_access_key
     * @param {string} options.s3_secret_key
     * @param {string} options.s3_bucket
     * @param {string} options.file - Path to the file to be uploaded
     * @param {string} [options.file_key] - Name to save the file under, defaults to the original file's name
     * @returns {Function} Promise - A promise resolved with `true` or rejected with an Error
     */
    upload: Promise.method(function upload(options) {
      var s3_options = {
        accessKeyId: options.s3_access_key,
        secretAccessKey: options.s3_secret_key,
        params: {
          Bucket: options.s3_bucket
        }
      };
      var file_stream = fs.createReadStream(options.file);
      var file_key = options.file_key || path.basename(options.file);
      var promisedS3 = Promise.promisifyAll(new AWS.S3(s3_options));

      return promisedS3.putObjectAsync({
        Body: file_stream,
        Key: file_key
      });
    })
  };
};

module.exports = {
  create: dispatcher
};

我知道如何进行集成测试,但我还想验证使用正确的参数调用promisedS3。我认为我需要使用间谍,但我不确定如何从测试中“插入”自己到promisedS3.putObjectAsync来拦截参数并进行比较。

我想避免在私有方法中包含对S3的调用,并继续使用工厂。

1 个答案:

答案 0 :(得分:1)

(评论后编辑)

在测试中,您可以使用像proxyquire这样的库来存根/模拟外部依赖项。

我刚刚对此进行了测试并且有效:

public void f(List<BinaryOperator<Integer>> op) {
    for (BinaryOperator<Integer> o : op) {
        int x = o.apply(1,2);
    }
}

'use strict'; var sinon = require( 'sinon' ); var proxyquire = require( 'proxyquire' ); var expect = require('must'); var awsStub = { S3: function(){ }, '@noCallThru': true }; var fsStub = { createReadStream: function(){ return {}; }, '@noCallThru': true }; describe( 'S3 uploader', function(){ var subject, spy; beforeEach( function(){ spy = sinon.spy(); awsStub.S3.prototype.putObject = function( params, callback ){ spy(params); callback(); }; subject = proxyquire( '../lib/s3uploader', { 'aws-sdk': awsStub, 'fs-extra': fsStub } ); } ); it( 'should delegate to AWS S3 `putObject`', function( done ){ subject().upload( {file:''} ).then( function(){ expect( spy.callCount ).to.equal( 1 ); done(); } ) } ); } ); 是您在上面发布的文件。

默认情况下,仍会调用存根依赖项的原始方法。如果您不希望您需要将lib/s3uploader传递给proxyquire调用,如上所述。