- 讀み取り専用
- on-memory で高速
- 再起動せずに新しい ver.の data へ入れ替へられる
- 古い ver.で處理してゐた計算はそのまま古い ver.を讀み出し續けられる
- heap 領域に cache できる。讀み出した data を snapshot として system 外に持ち運べる
- parallel
これらを滿たしたMnemonicsと云ふ Elixir の library を以前に作った。無停止 upgrade 出來るActiveHashの樣なものだ。
Mnemonics を使った code を test しやうとする。test で使ふ data は、實働環境から独立である必要が在る、即ち test で使ふ data はは test 内に書かれてあるのが好い。又 test で使ふ data は、他の test からも独立である必要が在る、即ち或る test が書き換へた data が他の test に影響しないのが好い。PostgreSQL 等の DB を使った code を test するには 2 つの方法が在る。ひとつには DB と遣り取りする函數を mock して了ふ。もうひとつは test 毎に一意な data を DB に書き込む。test 毎に一意であればその data は他のどこからも讀み出せない。RDB であれば通常は、一意な primary key を test の外で生成して 與へ、與へられた key の data 以外には手を触れないと取り決めてやる。所謂 test factory だ。Rails/ActiveRecord だとFactoryBotが有名だ。Elixir/Ecto だとExMachinaが有名である。例へばこう使ふ。
defmodule Factory do use ExMachina.Ecto def user_factory do id = sequence("") %User{id: String.to_integer(id), name: "user" <> id} end end defmodule UserTest do import Factory use ExUnit.Case test "authorized?" do user = insert(:user) assert User.authorized?(user) end end
some_factory
と云ふ函數を定義してやりuse ExMachina.Ecto
としてやると、build(:some)
とinsert(:some)
と云ふ函數が使へる樣に成る。
さて Mnemonics ではこれが出來ない。test 毎に一意な data を生成してやるのだが、readonly なので環境に書き込めない。
出來なかった。mock する手も在っただらうとは思ふものの、ETS をまるごと mock するのはダルいので、Mnemonics 側に書き込み出來る穴を空けてやった。この穴は table 毎に 1 つの GenServer であり parallel ではないので本番では使ってはならないが、test で使ふには充分速い。
こう使ふ。
defmodule Factory do use Mnemonics.ExMachina def item_factory do id = sequence("") %Item{id: String.to_integer(id), name: "user" <> id} end end defmodule UserTest do import Factory use ExUnit.Case test "drop?" do user = insert(:item) assert Item.drop?(item) end end
use ExMachina.Ecto
がuse Mnemonics.ExMachina
に變はっただけ。一つの factory に兩方を use する事は出來ないので、併用する時は 2 つ factory を作ってやり、尚且つ import せず full qualified に module 名附きで呼んでやれば好い。
ヾ(〃l _ l)ノ゙