Virtual AlexaでS3 Persistance Adapterを利用しているスキルのテストを実行するワークアラウンド
Virtual Alexaには、DynamoDBのモックはありますがS3のモックがありません。 つまりS3 Persistance Adapterを利用している場合、そのままではリアルにS3へのリクエストが飛んでしましま […]
目次
Virtual Alexaには、DynamoDBのモックはありますがS3のモックがありません。
つまりS3 Persistance Adapterを利用している場合、そのままではリアルにS3へのリクエストが飛んでしまします。
ということでとりあえずテストが動けばいいというタイプのワークアラウンドをまとめました。
結論:テストの時だけDynamoDBにする
身も蓋もないですね。だからワークアラウンドなのです。
基本的にどちらのアダプターを使用していても、内部の実装は変わりません。ただ、どこにデータが保存されるかが変わるだけです。
と、いうことはテストの時だけDynamoDBを使っていることにすれば、Virtual Alexaのモックが使えます。
Step1: Persistance Adapterをセットする前にexportする
まず、スキルのコードの書き方を少し変えます。一般的な書き方がこちら。
export const handler = Alexa.SkillBuilders.custom()
.addRequestHandlers(
...requestHandlers
).addRequestInterceptors(
...requestInterceptors
).addResponseInterceptors(
...responseInterceptors
).addErrorHandlers(
...errorHandlers
).withPersistenceAdapter(
new S3PersistenceAdapter({
bucketName: config.bucketName,
pathPrefix: config.bucketPathPrefix
})
).lambda()
これをこうします。
export const preBuildHandler = Alexa.SkillBuilders.custom()
.addRequestHandlers(
...requestHandlers
).addRequestInterceptors(
...requestInterceptors
).addResponseInterceptors(
...responseInterceptors
).addErrorHandlers(
...errorHandlers
)
export const handler = preBuildHandler
.withPersistenceAdapter(
new S3PersistenceAdapter({
bucketName: config.bucketName,
pathPrefix: config.bucketPathPrefix
})
).lambda()
Persistance Adapterをセットして、lambda()
を実行すれば終わりという状態のところで一旦exportします。
Step2: preBuildHandlerを使ってVirtual Alexa向けにセットアップ
あとはテストコード側でVirtual Alexa向けにセットアップしてやりましょう。
import { DynamoDbPersistenceAdapter } from 'ask-sdk-dynamodb-persistence-adapter'
import { preBuildHandler } from '../../index'
const handler = preBuildHandler..withPersistenceAdapter(
new DynamoDbPersistenceAdapter({
tableName: 'dummy'
})
).lambda()
モックしてしまうので、テーブル名などは適当でOKです。ただしprimary Keyを変更している場合はその設定も実施してやりましょう。
Step3: Virtual Alexaでテストを書く
あとは今まで通りにテストコードを書けばOKです。
import {VirtualAlexa} from 'virtual-alexa'
import { DynamoDbPersistenceAdapter } from 'ask-sdk-dynamodb-persistence-adapter'
import { preBuildHandler } from '../../index'
const handler = preBuildHandler..withPersistenceAdapter(
new DynamoDbPersistenceAdapter({
tableName: 'dummy'
})
).lambda()
describe('test', () => {
it("Accepts responses without dollars", async function () {
const alexa = VirtualAlexa.Builder()
.handler(handler)
.interactionModelFile("./models/ja-JP.json")
.create();
alexa.dynamoDB().mock()
const launchResponse = await alexa.launch();
expect(launchResponse.response.outputSpeech.ssml).toContain( "Welcome to guess the price");
})
})
alexa.dynamoDB().mock()
を忘れると存在しないDynamoDBテーブルを探し出して処理が落ちますので注意です。
実際のところ
あくまでワークアラウンドですので、これでずっといける保証はありません。
どちらかというと、Virtual Alexaに要望を出したりプルリクエストでS3 mockを実装してもらう方が健全的でしょう。