使用 mocha 调整 Nodejs 图像大小
Nodejs test image resizing with mocha
我在 nodejs
应用程序中使用 graphicmagick
调整了图像的大小。
问题是在编写单元测试时,我似乎找不到任何方向或示例。看到我正在使用第三方模块,我测试图像大小调整是否有意义?如果是,我如何为我的代码编写测试?
// 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!");
};
编写单元测试时的惯例是只测试孤立的单元。
所有外部依赖都应该是stubbed/mocked,所以你可以只检查你单元中的逻辑(在这种情况下你的单元就是你的模块)。
至于要测试什么,你的单元唯一的public方法是"GruntHandler",所以这是你唯一应该测试的方法,因为它是本单位向其他单位提供的服务。
为了替换所有模块的依赖,我喜欢使用proxyquire包。它用您可以控制的存根替换 "require" 调用。
我已经使用我个人使用的测试堆栈编写了一个示例测试:proxyquire、mocha、用于间谍的 sinon、用于断言的 chai。
设置 - 将其放入 "test-helper" 模块以要求所有测试文件:
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
我在 nodejs
应用程序中使用 graphicmagick
调整了图像的大小。
问题是在编写单元测试时,我似乎找不到任何方向或示例。看到我正在使用第三方模块,我测试图像大小调整是否有意义?如果是,我如何为我的代码编写测试?
// 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!");
};
编写单元测试时的惯例是只测试孤立的单元。 所有外部依赖都应该是stubbed/mocked,所以你可以只检查你单元中的逻辑(在这种情况下你的单元就是你的模块)。
至于要测试什么,你的单元唯一的public方法是"GruntHandler",所以这是你唯一应该测试的方法,因为它是本单位向其他单位提供的服务。
为了替换所有模块的依赖,我喜欢使用proxyquire包。它用您可以控制的存根替换 "require" 调用。
我已经使用我个人使用的测试堆栈编写了一个示例测试:proxyquire、mocha、用于间谍的 sinon、用于断言的 chai。
设置 - 将其放入 "test-helper" 模块以要求所有测试文件:
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