Nodejs测试图像使用mocha调整大小

时间:2015-03-02 16:56:22

标签: node.js mocha

我已使用graphicmagick调整nodejs应用中的图片大小。

问题是在编写单元测试时,我似乎无法找到任何方向或示例。我测试图像大小调整,看到我使用第三方模块是否有意义?如果是,我怎么能为我的代码编写测试?

// dependencies
var async = require('async');
var AWS = require('aws-sdk');
var gm = require('gm').subClass({ imageMagick: true });
var util = require('util');

// get reference to S3 client
var s3 = new AWS.S3();

var _800px = {
    width: 800,
    destinationPath: "large"
};

var _500px = {
    width: 500,
    destinationPath: "medium"
};

var _200px = {
    width: 200,
    destinationPath: "small"
};

var _45px = {
    width: 45,
    destinationPath: "thumbnail"
};

var _sizesArray = [_800px, _500px, _200px, _45px];

var len = _sizesArray.length;

// handler for dev environment

exports.GruntHandler = function (filepath) {

    console.log("Path to file is: " + filepath);

    // get the file name
    var srcFile = filepath.split("/").pop();

    var dstnFile = "dst";

    // Infer the image type.
    var typeMatch = srcFile.match(/\.([^.]*)$/);
    if (!typeMatch) {
        console.error('unable to infer image type for key ' + srcFile);
        return;
    }
    var imageType = typeMatch[1];
    if (imageType != "jpg" && imageType != "png") {
        console.log('skipping non-image ' + srcFile);
        return;
    }

    for (var i = 0; i<len; i++) {

        // Transform the image buffer in memory.
        gm(filepath)
            .resize(_sizesArray[i].width)
            .write(dstnFile + "/" + _sizesArray[i].destinationPath + "/" + srcFile, function (err) {
                if (err) {
                    console.log(err);
                }
            });
    }


   console.log(" grunt handler called!");
};

1 个答案:

答案 0 :(得分:2)

编写单元测试时的惯例是仅测试隔离单元。 所有外部依赖项都应该是存根/模拟的,因此您只能检查单元中的逻辑(在这种情况下,您的单元是您的模块)。

至于要测试的,你单位唯一的公共方法是“GruntHandler”,所以这是你应该测试的唯一方法,因为它是该单位提供给其他单位的服务。 / p>

为了替换所有模块的依赖项,我喜欢使用proxyquire包。它用您可以控制的存根替换“require”调用。

我使用我个人使用的测试堆栈编写了一个示例测试:proxyquire,mocha,sinon for spies,chai for assertions。

设置 - 将其置于“测试助手”模块中以要求所有测试文件:

var chai = require('chai');
var sinonChai = require("sinon-chai");
var expect = chai.expect;
var sinon = require('sinon');
chai.use(sinonChai);
var proxyquire = require('proxyquire');

在您的测试文件中:

require('./test-helper');
describe('Image Resizing module', function () {
  var gmSubclassStub = sinon.stub();

  var testedModule = proxyquire('path-to-tested-file', {
    'gm': {subClass: sinon.stub().returns(gmSubclassStub)}
  });

  describe.only('GruntHandler', function () {
    it("should call gm write with correct files", function () {
      // Arrange
      var filepath = 'pepo.jpg';

      // Spies are the methods you expect were actually called
      var write800Spy = sinon.spy();
      var write500Spy = sinon.spy();
      var write200Spy = sinon.spy();
      var write45Spy = sinon.spy();

      // This is a stub that will return the correct spy for each iteration of the for loop
      var resizeStub = sinon.stub();
      resizeStub.withArgs(800).returns({write:write800Spy});
      resizeStub.withArgs(500).returns({write:write500Spy});
      resizeStub.withArgs(200).returns({write:write200Spy});
      resizeStub.withArgs(45).returns({write:write45Spy});

      // Stub is used when you just want to simulate a returned value
      gmSubclassStub.withArgs(filepath).returns({resize:resizeStub});

      // Act - this calls the tested method
      testedModule.GruntHandler(filepath);

      // Assert
      expect(write800Spy).calledWith("dst/large/pepo.jpg");
      expect(write500Spy).calledWith("dst/medium/pepo.jpg");
      expect(write200Spy).calledWith("dst/small/pepo.jpg");
      expect(write45Spy).calledWith("dst/thumbnail/pepo.jpg");
    });
  });
});

有关sinon间谍,存根和嘲讽的更多信息:http://sinonjs.org/

代理商:https://github.com/thlorenz/proxyquire

这是一个关于所有这些的精彩教程:http://kroltech.com/2014/02/node-js-testing-with-mocha-chai-sinon-proxyquire/#.VPTS9fmUdV0