はじめに
テスト環境を作る際に色々と詰まった点を簡単にまとめてみます。
dynamodb-localなどの構築はこちらの記事で行っています
詰まった点1:dynamodb-localのコンテナを開発用とテスト用に分ける?
結論から言うと1つにまとめました。
dynamoidで勝手にテーブルを作成してくれるので、コンテナを分けないと開発用とテスト用で同じテーブルを使用することになってしまうのではと思いました。しかし、helperでdynamoidの設定を作成することでこの問題を解決することができました。
必要な設定
require 'spec_helper'
require 'dynamoid'
略
Dynamoid.configure do |config|
config.namespace = 'test'
config.region = 'ap-northeast-1'
config.endpoint = 'http://dynamodb-qiita-local:8000'
config.credentials = Aws::Credentials.new('test', 'test')
end
略
config.after :each, dynamodb: true do
Dynamoid.adapter.list_tables.each do |table|
# Only delete tables in our namespace
Dynamoid.adapter.delete_table(table) if table =~ /^#{Dynamoid::Config.namespace}/
end
# tablesにテーブル情報が残っているので削除
Dynamoid.adapter.tables.clear
# Recreate all tables to avoid unexpected errors
# テスト後にデータを削除したいのでコメントアウト、初期化でテーブルを作り直したい場合はコメントを外す
# [Test].each { |m| m.create_table(sync: true) }
end
end
・namespaceでtestと設定することで、テーブル名にtestが入るようになります
・delete_tableでテーブル名にnamespaceが含まれるものを削除しています
・エンドポイントはdynamodb-localのコンテナを指定しています
・credentialはダミー情報を設定しています
・テスト実行時にdynamoidの設定を反映するにはdynamodb: true
をrails_helper.rbとspecに記載する必要があります
require 'rails_helper'
RSpec.describe Hoge, type: :model, dynamodb: true do
略
end
詰まった点2:Dynamoid.adapter.tables.clearについて
テーブルを削除した後に実行しているDynamoid.adapter.tables.clear
がなぜ必要なのか気になったので、公式ドキュメントでadapterについて調べてみました。
するとdelete_tableメソッド内でtablesを参照していました。
delete_tableを実行するとdbからテーブルは削除されるのですが、tablesにはテーブル情報が残ってしまうようです。
なので、Dynamoid.adapter.tables.clearは必要でした。
def delete_table(table_name, options = {})
if tables.include?(table_name)
benchmark('Delete Table') { adapter.delete_table(table_name, options) }
idx = tables.index(table_name)
tables.delete_at(idx)
end
end
おわりに
これでテスト実行後にテストで作成したテーブルがdbから消えている状態になりました。
色々と詰まりましたが、良い勉強になりました。