Lambda Testこんなときどうするの
シリーズ化できたらいいな~
AWS Lambdaで複数のDBをscanしてる、このDBをstubにしたい
以下のようなケースについて☟
Lambda.js
//aws-sdkを定義
const AWS = require('aws-sdk')
//dynamo-DBを定義
const dynamo = new AWS.DynamoDB.DocumentClient()
// 野菜DBから全取得
// Dynamoの野菜DBの内容をscan
var yasaiDB = await dynamo.scan({ TableName: 'vegitable' }).promise()
// 八百屋DBから全取得
var yaoyaDB = await dynamo.scan({ TableName: 'Yaoya' }).promise()
野菜DB、八百屋DBそれぞれから情報をscanしてきて、その情報をほにゃほにゃしてる状況。
このLambdaをsinonやchaiでTestするとき、
この野菜DBと八百屋DBをstubするには、stubを2つ設定しないといけない?
ふつうにdynamo-DBのscanのstubつくるときはこんな風に書くけど…
Test_instance.js
// スタブでdb-scanしたとき、このアイテムを返すと約束する
const dynamoDBScan = sinon.stub(proxyDynamoDB.prototype, 'scan')
.returns({
promise: () => {
return Promise.resolve({
Items:
vegitableInfo
})
}})
どうしたらいいのだろうか…
sinonの公式ドキュメントにいい使い方が
sinon.stub.withArgs(***)で引数変えたときの返してほしい値を設定できるそう。
これが使える。
実際に書いたテストコード
Test.js
describe('yasai kounyuu system Lambda', () => {
let event
let context
let lambda
// it毎に毎回呼ばれる
beforeEach(() => {
event = {routeKey: 'GET'}
context = {}
},
// DynamoDBのstubを作成
proxyDynamoDB = class {
scan (params) {
return {
promise: () => {}
}
}
},
// テストしたいソースをここで定義
lambda = proxyquire('./Lambda.js', {
'aws-sdk': {
DynamoDB: {
DocumentClient: proxyDynamoDB
}
}
})
)
// スタブでdb-scanしたとき、このアイテムを返すと約束する
// ★ここからstubの引数による使い分け箇所★
const dynamoDBScan = sinon.stub(proxyDynamoDB.prototype, 'scan')
dynamoDBScan.withArgs({ TableName: 'vegitable' }).returns({
promise: () => {
return Promise.resolve({
Items:
vegitableInfo
})
}})
dynamoDBScan.withArgs({ TableName: 'Yaoya' }).returns({
promise: () => {
return Promise.resolve({
Items:
yaoyaInfo
})
}})
// テストしたいコードを書き足すときは、asyncにしないとバグる(まだデータないよってなる)
it('yasai TEST', async function () {
// ここでREST APIのCRUDをrouteKeyに設定する
var event = {routeKey: 'GET'}
// テストしたいソースを呼び出す
const resp = await lambda.handler(event, context)
// Stringできてるrespをparseする
const respBody = JSON.parse(resp.body)
// dynamoDBscanは2回呼ばれてるので、calledTwice(Onceではない)ですよー
assert.equal(dynamoDBScan.calledTwice, true)
})
sinonの公式ドキュメントはすごく親切
みんな読もう…!