【问题标题】:Howto pass correct JSON Event in Jest test of AWS Lambda local invocation如果 AWS Lambda 本地调用,如何在 Jest 测试中传递正确的 JSON 事件
【发布时间】:2019-09-11 06:06:03
【问题描述】:

我有一个 lambda(在 node.js 中),可以在生产环境中使用:

'use strict';

const AWS = require('aws-sdk');
const Politician = require('../model/politician.js');

const dynamoDb = new AWS.DynamoDB.DocumentClient();

module.exports.put = async (event, context) => {

    const requestBody = new Politician(JSON.parse(event.body));

    return await submit(requestBody)
        .then(res => {
            return {
                statusCode: 200,
                body: JSON.stringify({
                    message: `Successfully submitted politician with name ${requestBody.name}`,
                    politicianId: res.id
                })
            }

        })
        .catch(err => {
            return {
                statusCode: 500,
                body: JSON.stringify({
                    message: `Error while submitting politician with name ${requestBody.name}`,
                })
            }
        });

};

const submit = politician => {

    return new Promise((resolve, reject) => {
        if (politician) {
            resolve(politician);
        } else {
            reject(new Error('it all went bad!'));
        }
    });
};

在尝试设置 Lambda 的本地测试时出现问题(我使用的是Serverless framework)。问题是我似乎无法提供任何不会产生的事件格式:

SyntaxError: Unexpected token u in JSON at position 0

      12 |     console.log(typeof event.body);
      13 | 
    > 14 |     const requestBody = new Politician(JSON.parse(event.body));
         |                                             ^
      15 | 
      16 | 
      17 |     return await submit(requestBody)

          at JSON.parse (<anonymous>)
      at Object.parse [as put] (functions/coxon-put-politician.js:14:45)
      at Object.put (functions-test/coxon-put-politician.test.js:37:37)

所以它未定义,当我这样做时:

'use strict';
const AWS = require('aws-sdk');
const options = {
    region: 'localhost',
    endpoint: 'http://localhost:8000'
};
AWS.config.update(options);

const eventStub = require('../events/graham.richardson.json');
const lambda = require('../functions/coxon-put-politician');

describe('Service politicians: mock for successful operations', () => {

    test('Replies back with a JSON response', async () => {
        const event = '{"body":' + JSON.stringify(eventStub) + '}';
        const context = {};

        const result = await lambda.put(event, context);

        console.log(data);
        expect(result).toBeTruthy();
        expect(result.statusCode).toBe(200);
        expect(result.body).toBe(`{"result":"${result}"}`);
        expect(result.body.message.toContain('Successfully submitted politician'))

    });
});

或产生:

SyntaxError: Unexpected token o in JSON at position 1

      12 |     console.log(typeof event.body);
      13 | 
    > 14 |     const requestBody = new Politician(JSON.parse(event.body));
         |                                             ^
      15 | 
      16 | 
      17 |     return await submit(requestBody)

          at JSON.parse (<anonymous>)
      at Object.parse [as put] (functions/coxon-put-politician.js:14:45)
      at Object.put (functions-test/coxon-put-politician.test.js:38:37)

当我尝试这个时:

'use strict';
const AWS = require('aws-sdk');
const options = {
    region: 'localhost',
    endpoint: 'http://localhost:8000'
};
AWS.config.update(options);

const eventStub = require('../events/graham.richardson.json');
const lambda = require('../functions/coxon-put-politician');

describe('Service politicians: mock for successful operations', () => {

    test('Replies back with a JSON response', async () => {
        const event = { body: eventStub };
        const context = {};

        const result = await lambda.put(event, context);

        expect(result).toBeTruthy();
        expect(result.statusCode).toBe(200);
        expect(result.body).toBe(`{"result":"${result}"}`);
        expect(result.body.message.toContain('Successfully submitted politician'))

    });
});

因此,无论我走哪条路,我都会遇到错误。那么我应该将什么作为事件传递到测试中,以便 JSON.parse(event) 起作用?

【问题讨论】:

    标签: node.js aws-lambda jestjs serverless-framework


    【解决方案1】:

    TL;DR:const event = { body: JSON.stringify(eventStub) }

    您的生产代码有效,因为代码针对预期的有效负载结构正确编写,其中event 是一个对象,event.body 是一个 JSON 可解析字符串。

    在您的第一个测试中,您传递 event 不是作为对象,而是作为 JSON 可解析字符串。 event.body 未定义,因为 event 作为字符串没有 body 作为参数。

    您的测试应该是const event = { body: JSON.stringify(eventStub) },注意它是一个带有body 属性的对象,它是一个字符串。

    在您的第二次尝试中,您传递了一个对象,然后当您尝试 JSON.parse() 时,它抛出了一个错误。

    注意错误:

    位置 1 处 JSON 中的意外标记 o

    oobject... 的位置1,就像uundefined 的位置1。

    【讨论】:

    • 是的,就是这样。我知道某些组合会起作用,我想这是一种排列,我只是没有尝试。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-26
    • 1970-01-01
    • 2022-12-14
    • 1970-01-01
    • 2019-01-15
    • 2019-08-25
    • 1970-01-01
    相关资源
    最近更新 更多