node.js에서 사용되는 단위테스트 라이브러리 들에 대해 간단하게 예제를 정리해보았다.
작성자: ospace114@empal.com, http://ospace.tistory.com/
should.js
node.js 테스트 라이브러리
여러 asertion 함수 지원
설치
npm i --save-dev should
예제
10.should.be.equal(10)
[1,2].should.have.length(2)
({one:1}).should.have.properties('one')
({one:1}).should.have.properties({'one':1})
10.should.be.a.Number()
[1,2].should.be.instanceOf(Array)
Mocha
node.js 테스트 프레임워크, 테스트 러너
테스트 실행 코드에서 should.js로 작성됨
설치
npm i --save-dev mocha
기본 사용 구조
describe('unit test sample', function() {
before(function() {}); // test suite 실행 전
after(function() {}); // test suite 실행 후
beforeEach(function() {}); // unit test 실행 전
afterEach(function() {}); // unit test 실행 후
describe('#test01', function() { // test 범위 그룹핑
it('1st test', function() { // unit test 실행
// test code
});
});
});
러너
package.json에서 scripts에 아래 항목 추가해준다.
"test": "mocha"
sinon.js
Sequelize ORM을 mocking 지원
설치
npm i --save-dev sinnon
node-mocks-http
http의 request와 response에 대해 mocking 지원
설치
npm i --save-dev node-mocks-http
사용
const httpMocks = require('node-mocks-http');
const {eventEmitter} = require('events');
var req = httpMocks.createRequest({
method: 'GET',
url: '/user/42',
params: {
id: 42
}
});
var res = httpMocks.createResponse({
eventEmitter: myEventEmitter
});
response가 데이터전송시(send(), json()) 해당 eventEmitter가 'end' 이벤트를 호출해야 한다.
비동기 처리되는 라우팅함수 종료 시점을 알 수 있다.
var req, res, sandbox;
describe('unit test sample', function() {
before(function() {
sandbox = sinon.sandbox.create(); // sandbox 가상공간 제공
// stub로 함수 흉내냄.
sandbox.stub(db.list, 'findById', function() { // db.list의 findById 함수 흉내
return new Promise(function(resolve, reject) {
resolve({
id: 1,
name: "test list"
});
});
});
});
after(function() {
sandbox.restore();
});
beforeEach(function() {
req = httpMocks.createRequest();
res = httpMocks.createResponse({
eventEmitter: myEventEmitter
});
});
afterEach(function() {}); // unit test 실행 후
describe('#test01', function() { // test 범위 그룹핑
it('1st test', function(done) { // unit test 실행
res.on('end', function() { //eventEmiiter에 의해서 발생됨
var resData = JSON.parse(res._getData());
res.statusCode.should.be.equal(200);
resData.should
.be.instanceOf(Object)
.and.have.properties(['id', 'name']);
resData.id.should.be.equal(1);
resData.name.should.be.equal("test list");
done();
});
list.getList(req, res);
});
});
});
테스트 코드
간단한 테스트 코드를 작성해보자.
샘플 routes 추가
const models = require('../models');
exports.index = function(req, res, next) {
res.json([{
name: 'Chris',
}, {
name: 'Sam'
}]);
};
exports.show = function(req, res, next) {
models.foo.findOne({
where: {name: req.params.name}
}).then(function(foo) {
if(!foo) return res.send(404);
res.json(foo);
}, function(err) {
res.send(500, err);
});
};
models에 있는 sequlize 모델 객체는 별다르게 다루지 않는다. show()에서는 models의 foo 모델을 사용해서 데이터를 찾는다.
test.js 파일 작성
before에 sinon.stub()를 사용해서 models의 foo 모델 객체의 findOne 함수에 대한 목업생성.
그러면 routes/foo에서 show()함수에서 사용하는 foo의 findOne()은 sinon에 의해 정의된 findOne()를 호출
const foo = require('../routes/foo');
const should = require('should');
const httpMocks = require('node-mocks-http');
const models = require('../models');
const sinon = require('sinon');
var req, res;
describe('foos test', function () {
before(function () {
sinon.stub(models.foo, 'findOne').returns({
then: function (fn) {
fn({name: 'Foo'});
}
});
});
beforeEach(function() {
req = httpMocks.createRequest();
res = httpMocks.createResponse();
});
it('should return the statusCode 200', function () {
foo.index(req, res);
res.statusCode.should.be.equals(200);
});
it('should return user array', function () {
foo.index(req, res);
JSON.parse(res._getData()).should.be.an.instanceOf(Array).and.have.a.lengthOf(2);
});
it('should return a user', function () {
req.params.name = 'Foo';
foo.show(req, res);
JSON.parse(res._getData()).should.be.instanceOf(Object).and.have.a.property('name');
});
});
실행
test.js 파일이기 때문에 mocha에서는 기본으로 test.js 파일을 찾아서 실행한다.
mocha
명령처를 찾을 수 없다면 npx을 앞에 붙여서 실행해본다.
sandbox을 사용하는 경우
var sandbox;
describe('foos test', function () {
before(function () {
sandbox = sinon.sandbox.create();
sandbox.stub(models.foo, 'findOne').returns({
then: function (fn) {
fn({name: 'Foo'});
}
});
});
after(function() {
sandbox.restore();
});
…
});
참조
[1] http://guswnsxodlf.github.io/should-and-mocha
[2] http://guswnsxodlf.github.io/how-to-test-express
[3] https://github.com/howardabrams/node-mocks-http
'3.구현 > HTML5&Javascript' 카테고리의 다른 글
[HTML] 간단한 로딩화면 스피너 만들기 (0) | 2022.01.25 |
---|---|
Javascript XLSX 파일 읽기 (0) | 2021.12.24 |
[node.js] websocket 사용하기 (0) | 2021.11.15 |
[vue2] package 버전 및 빌드시간 사용 (0) | 2021.11.15 |
[vue2] vuetify 기본 구성 (0) | 2021.11.11 |