Node.js에서 MySQL(ORM 없음)을 어떻게 조롱합니까?
하고 Node.js
펠릭스의 의뢰인과 함께요ORM을 사용하지 않습니다.
나는 때문에 (DAL 이외의)node-mysql
할지 잘 CRUD가 있습니다.
어떻게 이 일을 해낼지 생각나는 거 없어?
사용하면을 붙일 수 .sinon은 모듈 전체에 mock 또는 을 붙일 수 있습니다.를 들어, '아까다', '아까다'가 있다고 해 보겠습니다.mysql
에는 "Module" 의 .query
:
var mock;
mock = sinon.mock(require('mysql'))
mock.expects('query').with(queryString, queryParams).yields(null, rows);
queryString
,queryParams
예상되는 입력입니다. rows
예상되는 출력입니다.
로 하는 mysql을 합니다.query
방법은 시논에 의해 차단되고 검증됩니다.
테스트 예상 섹션에서 다음을 수행해야 합니다.
mock.verify()
해체 시 mysql을 정상 기능으로 복원해야 합니다.
mock.restore()
데이터베이스를 mysql을 사용하는 자체 클래스로 추상화하는 것이 좋습니다.그런 다음 해당 클래스의 인스턴스를 require()를 사용하여 로드하는 대신 모델 생성자에게 전달할 수 있습니다.
이 설정을 통해 장치 테스트 파일 내의 모델에 모의 DB 인스턴스를 전달할 수 있습니다.
다음은 작은 예입니다.
// db.js
var Db = function() {
this.driver = require('mysql');
};
Db.prototype.query = function(sql, callback) {
this.driver... callback (err, results);
}
module.exports = Db;
// someModel.js
var SomeModel = function (params) {
this.db = params.db
}
SomeModel.prototype.getSomeTable (params) {
var sql = ....
this.db.query (sql, function ( err, res ) {...}
}
module.exports = SomeModel;
// in app.js
var db = new (require('./db.js'))();
var someModel = new SomeModel ({db:db});
var otherModel = new OtherModel ({db:db})
// in app.test.js
var db = {
query: function (sql, callback) { ... callback ({...}) }
}
var someModel = new SomeModel ({db:db});
node.js에 대해서는 잘 모릅니다만, 종래의 프로그래밍의 의미에서는, 이러한 테스트를 실시하려면 , 데이터 액세스 방법으로부터 추상화할 필요가 있습니다.다음과 같은 DAL 클래스를 만들 수 없습니까?
var DataContainer = function () {
}
DataContainer.prototype.getAllBooks = function() {
// call mysql api select methods and return results...
}
이제 테스트의 맥락에서 초기화 중에 다음과 같이 getAllBooks 클래스에 패치를 적용합니다.
DataContainer.prototype.getAllBooks = function() {
// Here is where you'd return your mock data in whatever format is expected.
return [];
}
테스트 코드가 호출되면 getAllBooks는 실제로 mysql을 호출하지 않고 모의 데이터를 반환하는 버전으로 대체됩니다.node.js에 대해서는 잘 모르기 때문에 대략적인 개요입니다.
저는 @kgilpin의 답변으로 시작해서 AWS Lambda에서 Mysql을 테스트하기 위해 다음과 같은 결과를 얻었습니다.
const sinon = require('sinon');
const LambdaTester = require('lambda-tester');
const myLambdaHandler = require( '../../lambdas/myLambda' ).handler;
const mockMysql = sinon.mock(require('mysql'));
const chai = require('chai');
const expect = chai.expect;
describe('Database Write Requests', function() {
beforeEach(() => {
mockMysql.expects('createConnection').returns({
connect: () => {
console.log('Succesfully connected');
},
query: (query, vars, callback) => {
callback(null, succesfulDbInsert);
},
end: () => {
console.log('Connection ended');
}
});
});
after(() => {
mockMysql.restore();
});
describe( 'A call to write to the Database with correct schema', function() {
it( 'results in a write success', function() {
return LambdaTester(myLambdaHandler)
.event(anObject)
.expectResult((result) => {
expect(result).to.equal(succesfulDbInsert);
});
});
});
describe( 'database errors', function() {
before(() => {
mockMysql.expects('createConnection').returns({
connect: () => {
console.log('Succesfully connected');
},
query: (query, vars, callback) => {
callback('Database error!', null);
},
end: () => {
console.log('Connection ended');
}
});
});
after(() => {
mockMysql.restore();
});
it( 'results in a callback error response', function() {
return LambdaTester(myLambdaHandler)
.event(anObject)
.expectError((err) => {
expect(err.message).to.equal('Something went wrong');
});
});
});
});
실제 데이터베이스 접속을 원하지 않았기 때문에 mysql 응답을 모두 수동으로 조롱했습니다.
는 by田에 다른 했습니다..returns
할 수 createConnection
.
hora를 사용하여 외부 종속성을 조롱할 수 있습니다.
또한 필릭스의 노드 샌드박스 모듈도 비슷한 기능을 할 수 있다고 생각합니다.
따라서 kgilpin의 동일한 컨텍스트를 사용하면 hora에서는 다음과 같이 됩니다.
var mock = horaa('mysql');
mock.hijack('query', function(queryString, queryParam) {
// do your fake db query (e.g., return fake expected data)
});
//SUT calls and asserts
mock.restore('query');
mysql 드라이버를 사용하려면 먼저 연결을 만들고 반환된 연결 컨트롤러의 apis를 사용해야 하므로 2단계 접근법이 필요합니다.
그것을 하는 데는 두 가지 방법이 있습니다.
createConnection을 stubbing하여 stubbed 연결을 반환한다.
셋업 중:
const sinon = require('sinon');
const mysql = require('mysql');
const {createConnection} = mysql;
let mockConnection;
sinon.stub(mysql, 'createConnection').callsFake((...args) => {
mockConnection = sinon.stub(createConnection.apply(mysql, args))
.expects('query').withArgs(.... )//program it how you like :)
return mockConnection;
})
const mockConnectionFactory =
sinon.stub(mysql)
.expects('createConnection')
해체 중:
mysql.createConnection.restore();
여기서 주의할 점은query
방법은 사례에서 조롱되고, 기초적인 메카니즘에 아무런 함의가 없기 때문에, 오직createConnection
를 복원해야 합니다.
stubbing, 접속 프로토타입에서의 .timeout 메서드
이 기술은 조금 더 까다롭습니다.mysql
드라이버가 공식적으로 Import 연결을 노출하지 않습니다.(접속을 구현하는 모듈만 Import할 수 있지만 리팩터링이 해당 모듈로 이동하지 않는다는 보장은 없습니다).프로토타입에 대한 참조를 얻기 위해 보통 연결을 만들고 생성자-프로토타입 체인을 따라 이동합니다.
보통 한 줄로 진행하는데, 단계별로 나누어 설명하겠습니다.
셋업 중:
const realConnection = mysql.createConnection({})
const mockTarget = realConnection.constructor.prototype;
//Then - brutally
consdt mock = sinon.mock(mockTarget).expect('query'....
//OR - as I prefer the surgical manner
sinon.stub(mockTarget, 'query').expect('query'....
해체 중
//brutal
mock.restore()
// - OR - surgical:
mockTarget.query.restore()
주의해 주세요.createConnection
방법은 이쪽입니다.모든 접속 파라미터 검증은 계속 진행됩니다(이러한 검증이 이루어지길 바랍니다).저는 최대한의 정규 부품으로 작업하고 싶습니다.따라서 빠른 테스트를 받기 위해 필요한 절대적인 최소 부품을 조롱합니다.)단, -query
프로토타입에서 조롱당했으므로 복원해야 합니다.
그리고 만약 당신이 수술을 한다면verify
mockTarget이 아닌 mockTarget에 있습니다.
여기 좋은 리소스가 있습니다.http://devdocs.io/sinon ~ 6 ~ 6 ~720s /
언급URL : https://stackoverflow.com/questions/8389149/how-do-you-mock-mysql-without-an-orm-in-node-js
'sourcecode' 카테고리의 다른 글
Java에서 범용 어레이 유형을 생성할 수 없는 이유는 무엇입니까? (0) | 2022.09.05 |
---|---|
개체 배열에서 .join on 값을 수행합니다. (0) | 2022.09.05 |
MySQL: 저장 프로시저에서 여러 필드를 여러 변수로 선택 (0) | 2022.09.05 |
클래스 메서드의 'self' 파라미터는 무엇입니까? (0) | 2022.09.05 |
TypeError: Vuex 4 및 Vue 3에서 사용할 때 정의되지 않은 속성 'getters'를 읽을 수 없습니다. (0) | 2022.09.05 |