Rumah > Soal Jawab > teks badan
Saya mempunyai titik akhir dalam Gateway API yang memetakan kepada fungsi Lambda dalam AWS. Apabila menulis kes ujian untuk fungsi pengendali baharu titik akhir, saya tidak mahu fail spec memanggil API sebenar atau menyambung ke DynamoDB. Saya cuba menambah sinon.stub
tetapi ia masih memanggil sambung ke DynamoDB dan kes ujian gagal. Saya tidak dapat mencari di mana silapnya tunas.
pengendali.js:
saveUser(userName, logger) { const Item = { id: uuid.v4(), userName, ttl: parseInt(Date.now() / 1000) + 900 // expire the name after 15 minutes from now }; const params = { TableName: "my-table-name", Item }; logger.log(`Saving new user name to DynamoDB: ${JSON.stringify(params)}`); return new Promise(function(resolve, reject) { db.put(params, function(err, _) { if (err) { logger.exception(`Unable to connect to DynamoDB to create: ${err}`); reject({ statusCode: 404, err }); } else { logger.log(`Saved data to DynamoDB: ${JSON.stringify(Item)}`); resolve({ statusCode: 201, body: Item }); } }); }); }
Handler.spec.js:
import AWS from "aws-sdk"; const db = new AWS.DynamoDB.DocumentClient({ apiVersion: "2012-08-10" }); describe("user-name-handler", function() { const sandbox = sinon.createSandbox(); afterEach(() => sandbox.restore()); it("Test saveUser() method", async function(done) { const { saveUser } = userHandler; sandbox.stub(db, "put") .returns(new Promise((resolve, _) => resolve({ statusCode: 200 }))); try { const result = await saveUser("Sample User", { log: () => {}, exception: () => {} }); expect(result).to.be.equal({ data: "some data" }); done(); } catch (err) { console.log(err); done(); } }); });
Ralat:
Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both.
Saya log objek err
melalui konsol dan ia memberi saya ralat ini, yang membuatkan saya fikir ia cuba menyambung ke DynamoDB.
Error: connect ENETUNREACH 127.0.0.1:80 at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1144:16) { message: 'Missing credentials in config, if using AWS_CONFIG_FILE, set AWS_SDK_LOAD_CONFIG=1', errno: 'ENETUNREACH', code: 'CredentialsError', syscall: 'connect', address: '127.0.0.1', port: 80, time: 2023-05-07T10:45:25.835Z, originalError: { message: 'Could not load credentials from any providers', errno: 'ENETUNREACH', code: 'CredentialsError', syscall: 'connect', address: '127.0.0.1', port: 80, time: 2023-05-07T10:45:25.835Z, originalError: [Object] }
Berkaitan: Cara menguji kaedah yang mengembalikan data daripada AWS DynamoDB
P粉7147807682024-03-22 18:19:12
Anda mengejek db
- 而不是 saveUser
实际使用的 db
yang diisytiharkan dalam fail ujian.
Penyelesaian adalah untuk memindahkan pengisytiharan db ke modulnya sendiri, contohnya: db.js
const AWS = require("aws-sdk"); const db = new AWS.DynamoDB.DocumentClient({ apiVersion: "2012-08-10" }); module.exports = db;
Kemudian dari saveUser
模块和测试中导入它 - 这样我们就可以模拟 saveUser
使用的同一个 db
contoh.
Dikemas kini
Saya berjaya menjalankan ujian menggunakan kod berikut:
Kod ujian:
const sinon = require('sinon'); const { saveUser } = require('../userHandler'); const { expect } = require('chai'); const db = require('../db'); describe('user-name-handler', function() { afterEach(() => sinon.restore()); it('Test saveUser() method', async function() { sinon.stub(db, 'put') .returns(new Promise((resolve, _) => resolve({ statusCode: 201, body: 'some data' }))); try { const result = await saveUser(db, 'Sample User', { log: () => {}, exception: () => {} }); expect(result).to.deep.equal({ statusCode: 201, body: 'some data' }); } catch (err) { console.log('err', err); } }); });
Fail pengendali pengguna:
const db = require('./db'); const saveUser = (db, userName, logger) => { const Item = { id: uuid.v4(), userName, ttl: parseInt(Date.now() / 1000) + 900 // expire the name after 15 minutes from now }; const params = { TableName: "my-table-name" }; logger.log(`Saving new user name to DynamoDB: ${JSON.stringify(params)}`); return db.put(params, function(err, _) { if (err) { logger.exception(`Unable to connect to DynamoDB to create: ${err}`); return reject({ statusCode: 404, err }); } else { logger.log(`Saved data to DynamoDB: ${JSON.stringify(Item)}`); return resolve({ statusCode: 201, body: Item }); } }); } module.exports = { saveUser };
pakej.json
{ "name": "play", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "mocha --timeout 5000" }, "author": "", "license": "ISC", "dependencies": { "aws-sdk": "^2.1373.0", "chai": "^4.3.7", "mocha": "^10.2.0", "sinon": "^15.0.4" } }
P粉4760461652024-03-22 16:16:37
Kami boleh memisahkan sambungan pangkalan data ke dalam fail yang berbeza dan mengimportnya ke dalam pelaksanaan pengendali serta fail spec.
db.js
import AWS from "aws-sdk"; const db = new AWS.DynamoDB.DocumentClient({ apiVersion: "2012-08-10" }); export default db;
yields()
fungsiStub tidak seharusnya mengembalikan Promise
,而应与 .yields()
pautan ke parameter yang akan diterima panggilan baliknya. Kita boleh menukar parameter untuk merangkumi pelbagai cabang kod.
describe("user-handler connection success", function () { const sandbox = sinon.createSandbox(); afterEach(() => sandbox.restore()); before(() => { sinon.stub(db, "put") .yields(null, true); sinon.stub(db, "get") .yields(null, { sampleKey: "sample value" }); sinon.stub(db, "delete") .yields(null, { sampleKey: "sample value" }); }); after(() => { db.put.restore(); db.get.restore(); db.delete.restore(); }); it("Test saveUser() method success", async function () { const result = await userHandler.saveToken("sample user", { log: () => {}, exception: () => {} }); expect(result.statusCode).to.be.equal(201); }); });
https://www.youtube.com/watch?v=vXDbmrh0xDQ