Con*_*nan 9 mocking node.js jestjs aws-lambda serverless-framework
我写了一个 lambda 如下。
处理程序.js
const aws = require('aws-sdk');
const dynamoDb = new aws.DynamoDB.DocumentClient();
const testHandler = async event => {
// some code
// ...
const user = await getUser(userId)
// ...
// some code
}
const promisify = foo => new Promise((resolve, reject) => {
foo((error, result) => {
if (error) {
reject(error)
} else {
resolve(result)
}
})
})
const getUser = (userId) => promisify(callback =>
dynamoDb.get({
TableName: 'test-table',
Key: {
"PK": `${userId}`,
"SK": `${userId}`
}
}, callback))
.then((user) => {
console.log(`Retrieved user: ${userId}`)
return user
})
module.exports = {
testHandler: testHandler,
getUser: getUser
}
Run Code Online (Sandbox Code Playgroud)
我想编写一个单元测试来测试该getUser
功能,所以我尝试了以下方法。
处理程序.test.js
const handler = require('../handler');
const AWS = require('aws-sdk')
const dynamoDbGetParameterPromise = jest.fn().mockReturnValue({
promise: jest.fn().mockResolvedValue({
PK: 'userId-123', SK: 'userId-123'
})
})
AWS.DynamoDB.DocumentClient = jest.fn().mockImplementation(() => ({
get: dynamoDbGetParameterPromise
}))
describe('test getUser', () => {
beforeEach(() => {
jest.resetModules()
});
test('get user success', async () => {
const user = { PK: 'userId-123', SK: 'userId-123' };
const result = await handler.getUser(userId);
expect(result).toEqual(user);
});
});
Run Code Online (Sandbox Code Playgroud)
错误如下。
ConfigError: Missing region in config
105 |
106 | const getUser = (userId) => promisify(callback =>
> 107 | dynamoDb.get({
| ^
108 | TableName: 'test-table',
109 | Key: {
110 | "PK": 'userId-123',
Run Code Online (Sandbox Code Playgroud)
看来测试仍然使用dynamoDb
in thehandler.js
而不是测试中的嘲笑。
关于如何正确连接模拟来测试功能有什么想法吗?提前致谢!
您可以通过添加来使用 jest 的自动模拟
jest.mock("aws-sdk");
Run Code Online (Sandbox Code Playgroud)
然后AWS.DynamoDB.DocumentClient
将是一个模拟类,因此您将能够模拟它的实现。因为我们希望它的 get 方法成为一个接受任何东西作为第一个参数的函数(因为我们不会在模拟实现中对它做任何事情)和一个我们期望它被调用的回调,null
我们user
可以像这样嘲笑它:
AWS.DynamoDB.DocumentClient.prototype.get.mockImplementation((_, cb) => {
cb(null, user);
});
Run Code Online (Sandbox Code Playgroud)
您可以使用jest.mock(moduleName,factory,options)手动模拟aws-sdk
模块。
例如
\nhandler.js
:
const aws = require(\'aws-sdk\');\nconst dynamoDb = new aws.DynamoDB.DocumentClient();\n\nconst promisify = (foo) =>\n new Promise((resolve, reject) => {\n foo((error, result) => {\n if (error) {\n reject(error);\n } else {\n resolve(result);\n }\n });\n });\n\nconst getUser = (userId) =>\n promisify((callback) =>\n dynamoDb.get(\n {\n TableName: \'test-table\',\n Key: {\n PK: `${userId}`,\n SK: `${userId}`,\n },\n },\n callback,\n ),\n ).then((user) => {\n console.log(`Retrieved user: ${userId}`);\n return user;\n });\n\nmodule.exports = { getUser };\n
Run Code Online (Sandbox Code Playgroud)\nhandler.test.js
:
const aws = require(\'aws-sdk\');\nconst { getUser } = require(\'./handler\');\n\njest.mock(\'aws-sdk\', () => {\n const mDocumentClient = { get: jest.fn() };\n const mDynamoDB = { DocumentClient: jest.fn(() => mDocumentClient) };\n return { DynamoDB: mDynamoDB };\n});\nconst mDynamoDb = new aws.DynamoDB.DocumentClient();\n\ndescribe(\'64564233\', () => {\n afterAll(() => {\n jest.resetAllMocks();\n });\n it(\'should get user\', async () => {\n const mResult = { name: \'teresa teng\' };\n mDynamoDb.get.mockImplementationOnce((_, callback) => callback(null, mResult));\n const actual = await getUser(1);\n expect(actual).toEqual({ name: \'teresa teng\' });\n expect(mDynamoDb.get).toBeCalledWith(\n {\n TableName: \'test-table\',\n Key: {\n PK: \'1\',\n SK: \'1\',\n },\n },\n expect.any(Function),\n );\n });\n\n it(\'should handler error\', async () => {\n const mError = new Error(\'network\');\n mDynamoDb.get.mockImplementationOnce((_, callback) => callback(mError));\n await expect(getUser(1)).rejects.toThrowError(\'network\');\n expect(mDynamoDb.get).toBeCalledWith(\n {\n TableName: \'test-table\',\n Key: {\n PK: \'1\',\n SK: \'1\',\n },\n },\n expect.any(Function),\n );\n });\n});\n
Run Code Online (Sandbox Code Playgroud)\n单元测试结果:
\n PASS src/stackoverflow/64564233/handler.test.js (14.929s)\n 64564233\n \xe2\x9c\x93 should get user (23ms)\n \xe2\x9c\x93 should handler error (3ms)\n\n console.log src/stackoverflow/64564233/handler.js:433\n Retrieved user: 1\n\n------------|----------|----------|----------|----------|-------------------|\nFile | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |\n------------|----------|----------|----------|----------|-------------------|\nAll files | 100 | 100 | 100 | 100 | |\n handler.js | 100 | 100 | 100 | 100 | |\n------------|----------|----------|----------|----------|-------------------|\nTest Suites: 1 passed, 1 total\nTests: 2 passed, 2 total\nSnapshots: 0 total\nTime: 17.435s\n
Run Code Online (Sandbox Code Playgroud)\n源代码:https ://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/64564233
\n 归档时间: |
|
查看次数: |
15190 次 |
最近记录: |