J'ai un point de terminaison dans API Gateway qui correspond à une fonction Lambda dans AWS. Lors de l'écriture de cas de test pour la nouvelle fonction de gestionnaire du point de terminaison, je ne souhaite pas que le fichier spec appelle l'API réelle ou se connecte à DynamoDB. J'ai essayé d'ajouter sinon.stub
mais il appelle toujours la connexion à DynamoDB et le scénario de test échoue. Je ne trouve pas où le talon se trompe.
handler.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(); } }); });
Erreur :
Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both.
J'ai connecté l'objet err
via la console et cela m'a donné cette erreur, ce qui me fait penser qu'il essaie de se connecter à 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] }
Connexe : Comment tester les méthodes qui renvoient des données depuis AWS DynamoDB
Vous vous moquez du
db
- 而不是saveUser
实际使用的db
déclaré dans le fichier de test.La solution est de déplacer la déclaration db vers son propre module, par exemple : db.js
Puis à partir de l'instance
saveUser
模块和测试中导入它 - 这样我们就可以模拟saveUser
使用的同一个db
.Mise à jour
J'ai pu exécuter le test avec succès en utilisant le code suivant :
Code de test :
Fichier du gestionnaire d'utilisateur :
package.json
Sortie
Connexions de base de données séparées dans les fichiers
Nous pouvons séparer la connexion à la base de données en différents fichiers et les importer dans l'implémentation du gestionnaire ainsi que dans le fichier spec.
db.js
yields()
fonctionLe stub ne doit pas renvoyer directement
Promise
,而应与.yields()
un lien vers les paramètres que son rappel acceptera. Nous pouvons modifier les paramètres pour couvrir différentes branches du code.Code
Liens utiles
https://www.youtube.com/watch?v=vXDbmrh0xDQ