如何模拟 AWS RDSDataService 方法?
How to mock AWS RDSDataService methods?
我有一个数据库文件(不是 class)执行如下所示的更新操作 -
/* database operations file - NOT A CLASS */
import * as AWS from 'aws-sdk';
AWS.config.update({
region: 'us-west-2'
});
//.... set resourceARN, secretARN and other params to be passed to
const secretARN = process.env['SECRETARN'];
const resourceARN = process.env['RESOURCEARN'];
const rdsDataService = new AWS.RDSDataService();
const databaseName = process.env['DATABASE'];
// update query here
const addID = async(myID:string, userIds:string[], param3:string) => {
// .....some validation on the parameters
const userIdlist = userIds.join();
const updateQuery = 'my update sql query';
const sqlParams:any = {
secretArn: secretARN,
resourceArn: resourceARN,
sql: updateQuery,
database: databaseName,
includeResultMetadata: true
}
// run SQL command
await rdsDataService.executeStatement(sqlParams).promise()
.then(() => { logger.info('Update Query succeeded') })
.catch((error) => { logger.info(error); throw new Error('Unable to perform update for given users') });
};
export default {
addID
}
这是我的测试文件-
import * as sinon from 'sinon';
import chai from 'chai';
import * as AWS from 'aws-sdk';
import chaiaspromised from 'chai-as-promised';
import AWSMock from 'aws-sdk-mock';
import proxyquire from 'proxyquire';
chai.use(chaiaspromised);
const expect = chai.expect;
describe('Test Database component', () => {
it('add ID should be successful when all arguments are provided correctly', async () => {
AWSMock.setSDKInstance(AWS);
const rdstub = AWSMock.mock('RDSDataService', 'executeStatement', function (params, callback){
callback(null, 'successfully put item in database');
});
const dbops = proxyquire('path to the database file above', {rdsDataService:rdstub}).default;
expect(await dbops.addRegulationID('xyz', ['101', '102'], 'xyz')).to.not.throw();
AWSMock.restore('AWS.RDSDataService');
});
});
每当我 运行 测试时,我都会收到如下错误 -
Test Database component
1) add ID should be successful when all arguments are provided correctly
0 passing (4s)
1 failing
1) Test Database component add ID should be successful when all arguments are provided correctly:
Error: Unable to perform update for given users
at lib/dbops.ts:96:55
如何模拟 RDSDataService 的 executeStatement API?我需要一个单独的模拟库吗?在为 npm 库引用了几个示例后,我尝试了上面的方法,但不知何故,模拟似乎不适用于 RDSDataService。我哪里错了?
proxyquire
和sinon
包就够了,不需要用aws-sdk-mock
包。
index.ts
:
import * as AWS from 'aws-sdk';
AWS.config.update({ region: 'us-west-2' });
const secretARN = process.env['SECRETARN'];
const resourceARN = process.env['RESOURCEARN'];
const databaseName = process.env['DATABASE'];
const rdsDataService = new AWS.RDSDataService();
const addID = async (myID: string, userIds: string[], param3: string) => {
const updateQuery = 'my update sql query';
const sqlParams: any = {
secretArn: secretARN,
resourceArn: resourceARN,
sql: updateQuery,
database: databaseName,
includeResultMetadata: true,
};
await rdsDataService
.executeStatement(sqlParams)
.promise()
.then(() => {
console.info('Update Query succeeded');
})
.catch((error) => {
console.info(error);
throw new Error('Unable to perform update for given users');
});
};
export default { addID };
index.test.ts
:
import sinon from 'sinon';
import chai, { expect } from 'chai';
import chaiaspromised from 'chai-as-promised';
import proxyquire from 'proxyquire';
chai.use(chaiaspromised);
describe('69592200', () => {
it('should execute statement correctly', async () => {
const rdsDataService = {
executeStatement: sinon.stub().returnsThis(),
promise: sinon.stub().resolves(),
};
const AWSStub = {
RDSDataService: sinon.stub().returns(rdsDataService),
config: {
update: sinon.stub(),
},
};
const dbops = proxyquire('./', {
'aws-sdk': AWSStub,
}).default;
await dbops.addID('xyz', ['101', '102'], 'xyz');
sinon.assert.calledWithExactly(AWSStub.config.update, { region: 'us-west-2' });
sinon.assert.calledOnce(rdsDataService.executeStatement);
sinon.assert.calledOnce(rdsDataService.promise);
});
it('should throw error if execute query statement fail', async () => {
const error = new Error('network');
const rdsDataService = {
executeStatement: sinon.stub().returnsThis(),
promise: sinon.stub().rejects(error),
};
const AWSStub = {
RDSDataService: sinon.stub().returns(rdsDataService),
config: {
update: sinon.stub(),
},
};
const dbops = proxyquire('./', {
'aws-sdk': AWSStub,
}).default;
await expect(dbops.addID('xyz', ['101', '102'], 'xyz')).to.eventually.rejectedWith(
'Unable to perform update for given users',
);
});
});
测试结果:
69592200
Update Query succeeded
✓ should execute statement correctly (3974ms)
Error: network
at /Users/dulin/workspace/github.com/mrdulin/expressjs-research/src/Whosebug/69592200/index.test.ts:30:19
at Generator.next (<anonymous>)
at /Users/dulin/workspace/github.com/mrdulin/expressjs-research/src/Whosebug/69592200/index.test.ts:27:71
at new Promise (<anonymous>)
at __awaiter (/Users/dulin/workspace/github.com/mrdulin/expressjs-research/src/Whosebug/69592200/index.test.ts:23:12)
at Context.<anonymous> (/Users/dulin/workspace/github.com/mrdulin/expressjs-research/src/Whosebug/69592200/index.test.ts:29:71)
at callFn (/Users/dulin/workspace/github.com/mrdulin/expressjs-research/node_modules/mocha/lib/runnable.js:364:21)
at Test.Runnable.run (/Users/dulin/workspace/github.com/mrdulin/expressjs-research/node_modules/mocha/lib/runnable.js:352:5)
at Runner.runTest (/Users/dulin/workspace/github.com/mrdulin/expressjs-research/node_modules/mocha/lib/runner.js:677:10)
at /Users/dulin/workspace/github.com/mrdulin/expressjs-research/node_modules/mocha/lib/runner.js:801:12
at next (/Users/dulin/workspace/github.com/mrdulin/expressjs-research/node_modules/mocha/lib/runner.js:594:14)
at /Users/dulin/workspace/github.com/mrdulin/expressjs-research/node_modules/mocha/lib/runner.js:604:7
at next (/Users/dulin/workspace/github.com/mrdulin/expressjs-research/node_modules/mocha/lib/runner.js:486:14)
at Immediate.<anonymous> (/Users/dulin/workspace/github.com/mrdulin/expressjs-research/node_modules/mocha/lib/runner.js:572:5)
at processImmediate (internal/timers.js:461:21)
✓ should throw error if execute query statement fail
2 passing (4s)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
index.ts | 100 | 100 | 100 | 100 |
----------|---------|----------|---------|---------|-------------------
我有一个数据库文件(不是 class)执行如下所示的更新操作 -
/* database operations file - NOT A CLASS */
import * as AWS from 'aws-sdk';
AWS.config.update({
region: 'us-west-2'
});
//.... set resourceARN, secretARN and other params to be passed to
const secretARN = process.env['SECRETARN'];
const resourceARN = process.env['RESOURCEARN'];
const rdsDataService = new AWS.RDSDataService();
const databaseName = process.env['DATABASE'];
// update query here
const addID = async(myID:string, userIds:string[], param3:string) => {
// .....some validation on the parameters
const userIdlist = userIds.join();
const updateQuery = 'my update sql query';
const sqlParams:any = {
secretArn: secretARN,
resourceArn: resourceARN,
sql: updateQuery,
database: databaseName,
includeResultMetadata: true
}
// run SQL command
await rdsDataService.executeStatement(sqlParams).promise()
.then(() => { logger.info('Update Query succeeded') })
.catch((error) => { logger.info(error); throw new Error('Unable to perform update for given users') });
};
export default {
addID
}
这是我的测试文件-
import * as sinon from 'sinon';
import chai from 'chai';
import * as AWS from 'aws-sdk';
import chaiaspromised from 'chai-as-promised';
import AWSMock from 'aws-sdk-mock';
import proxyquire from 'proxyquire';
chai.use(chaiaspromised);
const expect = chai.expect;
describe('Test Database component', () => {
it('add ID should be successful when all arguments are provided correctly', async () => {
AWSMock.setSDKInstance(AWS);
const rdstub = AWSMock.mock('RDSDataService', 'executeStatement', function (params, callback){
callback(null, 'successfully put item in database');
});
const dbops = proxyquire('path to the database file above', {rdsDataService:rdstub}).default;
expect(await dbops.addRegulationID('xyz', ['101', '102'], 'xyz')).to.not.throw();
AWSMock.restore('AWS.RDSDataService');
});
});
每当我 运行 测试时,我都会收到如下错误 -
Test Database component
1) add ID should be successful when all arguments are provided correctly
0 passing (4s)
1 failing
1) Test Database component add ID should be successful when all arguments are provided correctly:
Error: Unable to perform update for given users
at lib/dbops.ts:96:55
如何模拟 RDSDataService 的 executeStatement API?我需要一个单独的模拟库吗?在为 npm 库引用了几个示例后,我尝试了上面的方法,但不知何故,模拟似乎不适用于 RDSDataService。我哪里错了?
proxyquire
和sinon
包就够了,不需要用aws-sdk-mock
包。
index.ts
:
import * as AWS from 'aws-sdk';
AWS.config.update({ region: 'us-west-2' });
const secretARN = process.env['SECRETARN'];
const resourceARN = process.env['RESOURCEARN'];
const databaseName = process.env['DATABASE'];
const rdsDataService = new AWS.RDSDataService();
const addID = async (myID: string, userIds: string[], param3: string) => {
const updateQuery = 'my update sql query';
const sqlParams: any = {
secretArn: secretARN,
resourceArn: resourceARN,
sql: updateQuery,
database: databaseName,
includeResultMetadata: true,
};
await rdsDataService
.executeStatement(sqlParams)
.promise()
.then(() => {
console.info('Update Query succeeded');
})
.catch((error) => {
console.info(error);
throw new Error('Unable to perform update for given users');
});
};
export default { addID };
index.test.ts
:
import sinon from 'sinon';
import chai, { expect } from 'chai';
import chaiaspromised from 'chai-as-promised';
import proxyquire from 'proxyquire';
chai.use(chaiaspromised);
describe('69592200', () => {
it('should execute statement correctly', async () => {
const rdsDataService = {
executeStatement: sinon.stub().returnsThis(),
promise: sinon.stub().resolves(),
};
const AWSStub = {
RDSDataService: sinon.stub().returns(rdsDataService),
config: {
update: sinon.stub(),
},
};
const dbops = proxyquire('./', {
'aws-sdk': AWSStub,
}).default;
await dbops.addID('xyz', ['101', '102'], 'xyz');
sinon.assert.calledWithExactly(AWSStub.config.update, { region: 'us-west-2' });
sinon.assert.calledOnce(rdsDataService.executeStatement);
sinon.assert.calledOnce(rdsDataService.promise);
});
it('should throw error if execute query statement fail', async () => {
const error = new Error('network');
const rdsDataService = {
executeStatement: sinon.stub().returnsThis(),
promise: sinon.stub().rejects(error),
};
const AWSStub = {
RDSDataService: sinon.stub().returns(rdsDataService),
config: {
update: sinon.stub(),
},
};
const dbops = proxyquire('./', {
'aws-sdk': AWSStub,
}).default;
await expect(dbops.addID('xyz', ['101', '102'], 'xyz')).to.eventually.rejectedWith(
'Unable to perform update for given users',
);
});
});
测试结果:
69592200
Update Query succeeded
✓ should execute statement correctly (3974ms)
Error: network
at /Users/dulin/workspace/github.com/mrdulin/expressjs-research/src/Whosebug/69592200/index.test.ts:30:19
at Generator.next (<anonymous>)
at /Users/dulin/workspace/github.com/mrdulin/expressjs-research/src/Whosebug/69592200/index.test.ts:27:71
at new Promise (<anonymous>)
at __awaiter (/Users/dulin/workspace/github.com/mrdulin/expressjs-research/src/Whosebug/69592200/index.test.ts:23:12)
at Context.<anonymous> (/Users/dulin/workspace/github.com/mrdulin/expressjs-research/src/Whosebug/69592200/index.test.ts:29:71)
at callFn (/Users/dulin/workspace/github.com/mrdulin/expressjs-research/node_modules/mocha/lib/runnable.js:364:21)
at Test.Runnable.run (/Users/dulin/workspace/github.com/mrdulin/expressjs-research/node_modules/mocha/lib/runnable.js:352:5)
at Runner.runTest (/Users/dulin/workspace/github.com/mrdulin/expressjs-research/node_modules/mocha/lib/runner.js:677:10)
at /Users/dulin/workspace/github.com/mrdulin/expressjs-research/node_modules/mocha/lib/runner.js:801:12
at next (/Users/dulin/workspace/github.com/mrdulin/expressjs-research/node_modules/mocha/lib/runner.js:594:14)
at /Users/dulin/workspace/github.com/mrdulin/expressjs-research/node_modules/mocha/lib/runner.js:604:7
at next (/Users/dulin/workspace/github.com/mrdulin/expressjs-research/node_modules/mocha/lib/runner.js:486:14)
at Immediate.<anonymous> (/Users/dulin/workspace/github.com/mrdulin/expressjs-research/node_modules/mocha/lib/runner.js:572:5)
at processImmediate (internal/timers.js:461:21)
✓ should throw error if execute query statement fail
2 passing (4s)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
index.ts | 100 | 100 | 100 | 100 |
----------|---------|----------|---------|---------|-------------------