我正在尝试用Sinon模拟SES,但是面临以下错误。已尝试使用aws-sdk-mock,但无法正常工作。
Error: TypeError: Cannot stub non-existent own property sendEmail
测试类的代码段:
import * as AWS from 'aws-sdk';
const sandbox = sinon.createSandbox();
sandbox.stub(AWS.SES, 'sendEmail').returns({promise: () => true});
实际班级:
import * as AWS from 'aws-sdk';
import * as _ from 'lodash';
export async function sendAlertMailOnFailure(status:any)
{
// load AWS SES
var ses = new AWS.SES();
const params = {
Destination: {
ToAddresses: <to_address>
},
Message: {...},
Source: <sender_address>
}
ses.sendEmail(params, (err, data) => {
if (err) {
log.error("Error sending mail::");
log.error(err, err.stack);
}
})
}
是否可以用Sinon或aws-sdk-mock模拟SES?
答案 0 :(得分:1)
您需要使用 <?php
if(isset($_POST["insert"]))
{
$file = addslashes(file_get_contents($_FILES["image"]["tmp_name"]));
$query = "INSERT INTO tbl_images(name) VALUES ('$file')";
if(mysqli_query($connection, $query))
{
echo '<script>alert("Image Inserted into Database")</script>';
}
}
?>
中的prototype
对其进行存根:
AWS
答案 1 :(得分:0)
该错误似乎表明AWS
被导入为undefined
。
可能是您的ES6编译器没有自动改变这一行:
import AWS from 'aws-sdk';
...导入aws-sdk
中的所有内容到AWS
中。
将其更改为此:
import * as AWS from 'aws-sdk';
...这可能会解决问题。
(免责声明:我无法在使用Babel
v7编译并自动处理任一方法的环境中重现该错误)
答案 2 :(得分:0)
使用require&而不使用原型。这对我来说可以模拟DynamoDB。
const aws = require('aws-sdk');
const sinon = require('sinon');
const sandbox = sinon.createSandbox();
this.awsStub = sandbox.stub(aws, 'DynamoDB').returns({
query: function() {
return {
promise: function() {
return {
Items: []
};
}
};
}
});
包装:
“ aws-sdk”:“ ^ 2.453.0”
“ sinon”:“ ^ 7.3.2”
答案 3 :(得分:0)
我的回答不是SES
的直接解决方案,而是 我用来模拟DynamoDB.DocumentClient
和SQS
的有效解决方案。也许您可以在单元测试中为SES
和其他aws-sdk
客户使用我的工作示例。
我只是花了几个小时尝试使AWS SQS模拟工作正常,没有求助于在功能内导入aws-sdk-mock
客户端的aws-sdk
要求。
AWS.DynamoDB.DocumentClient
的模拟非常简单,但是AWS.SQS
的模拟让我很困惑,直到我遇到使用rewire的建议。
我的lambda将错误消息移至SQS FailQueue(而不是让Lambda失败并将消息返回至常规Queue以进行重试,然后在maxRetries之后将DeadLetterQueue返回)。模拟以下SQS方法所需的单元测试:
SQS.getQueueUrl
SQS.sendMessage
SQS.deleteMessage
在尽量包括所有相关部分的同时,我将尽量简化示例代码:
我的AWS Lambda(index.js)的片段:
const AWS = require('aws-sdk');
AWS.config.update({region:'eu-west-1'});
const docClient = new AWS.DynamoDB.DocumentClient();
const sqs = new AWS.SQS({ apiVersion: '2012-11-05' });
// ...snip
删节的Lambda事件记录(event.json)
{
"valid": {
"Records": [{
"messageId": "c292410d-3b27-49ae-8e1f-0eb155f0710b",
"receiptHandle": "AQEBz5JUoLYsn4dstTAxP7/IF9+T1S994n3FLkMvMmAh1Ut/Elpc0tbNZSaCPYDvP+mBBecVWmAM88SgW7iI8T65Blz3cXshP3keWzCgLCnmkwGvDHBYFVccm93yuMe0i5W02jX0s1LJuNVYI1aVtyz19IbzlVksp+z2RxAX6zMhcTy3VzusIZ6aDORW6yYppIYtKuB2G4Ftf8SE4XPzXo5RCdYirja1aMuh9DluEtSIW+lgDQcHbhIZeJx0eC09KQGJSF2uKk2BqTGvQrknw0EvjNEl6Jv56lWKyFT78K3TLBy2XdGFKQTsSALBNtlwFd8ZzcJoMaUFpbJVkzuLDST1y4nKQi7MK58JMsZ4ujZJnYvKFvgtc6YfWgsEuV0QSL9U5FradtXg4EnaBOnGVTFrbE18DoEuvUUiO7ZQPO9auS4=",
"body": "{ \"key1\": \"value 1\", \"key2\": \"value 2\", \"key3\": \"value 3\", \"key4\": \"value 4\", \"key5\": \"value 5\" }",
"attributes": {
"ApproximateReceiveCount": "1",
"SentTimestamp": "1536763724607",
"SenderId": "AROAJAAXYIAN46PWMV46S:steve.goossens@bbc.co.uk",
"ApproximateFirstReceiveTimestamp": "1536763724618"
},
"messageAttributes": {},
"md5OfBody": "e5b16f3a468e6547785a3454cfb33293",
"eventSource": "aws:sqs",
"eventSourceARN": "arn:aws:sqs:eu-west-1:123456789012:sqs-queue-name",
"awsRegion": "eu-west-1"
}]
}
}
节略的单元测试文件(test / index.test.js):
const AWS = require('aws-sdk');
const expect = require('chai').expect;
const LamdbaTester = require('lambda-tester');
const rewire = require('rewire');
const sinon = require('sinon');
const event = require('./event');
const lambda = rewire('../index');
let sinonSandbox;
function mockGoodSqsMove() {
const promiseStubSqs = sinonSandbox.stub().resolves({});
const sqsMock = {
getQueueUrl: () => ({ promise: sinonSandbox.stub().resolves({ QueueUrl: 'queue-url' }) }),
sendMessage: () => ({ promise: promiseStubSqs }),
deleteMessage: () => ({ promise: promiseStubSqs })
}
lambda.__set__('sqs', sqsMock);
}
describe('handler', function () {
beforeEach(() => {
sinonSandbox = sinon.createSandbox();
});
afterEach(() => {
sinonSandbox.restore();
});
describe('when SQS message is in dedupe cache', function () {
beforeEach(() => {
// mock SQS
mockGoodSqsMove();
// mock DynamoDBClient
const promiseStub = sinonSandbox.stub().resolves({'Item': 'something'});
sinonSandbox.stub(AWS.DynamoDB.DocumentClient.prototype, 'get').returns({ promise: promiseStub });
});
it('should return an error for a duplicate message', function () {
return LamdbaTester(lambda.handler)
.event(event.valid)
.expectReject((err, additional) => {
expect(err).to.have.property('message', 'Duplicate message: {"Item":"something"}');
});
});
});
});
答案 4 :(得分:0)
通过执行以下操作,我可以使用awk-sdk-mock:
测试班
const AWSMock = require('aws-sdk-mock');
const AWS = require('aws-sdk');
AWSMock.setSDKInstance(AWS);
...
AWSMock.mock('SES', 'sendRawEmail', mockSendEmail);
// call method that needs to mock send an email goes below
sendEmail(to, from, subject, body, callback);
function mockSendEmail(params, callback) {
console.log('mock email');
return callback({
MessageId: '1234567',
});
}
实际班
const aws = require('aws-sdk');
const nodemailer = require('nodemailer');
function sendEmail(to, from, subject, body, callback) {
let addresses = to;
if (!Array.isArray(addresses)) {
addresses = [addresses];
}
let replyTo = [];
if (from) {
replyTo.push(from);
}
let data = {
to: addresses,
replyTo,
subject,
text: body,
};
nodemailer.createTransport({ SES: new aws.SES({ apiVersion: '2010-12-01' }) }).sendMail(data, callback);
}
答案 5 :(得分:0)
const AWS = require('aws-sdk');
...
const sandbox = sinon.createSandbox();
sandbox.stub(AWS, 'SES').returns({
sendRawEmail: () => {
console.log("My sendRawEmail");
return {
promise: function () {
return {
MessageId: '987654321'
};
}
};
}
});
let ses = new AWS.SES({ region: 'us-east-1' });
let result = ses.sendRawEmail(params).promise();