これはなに?
- 2019-01-25 の YAPC::Tokyo 前夜祭のLTで使ったスライド
- ネタ画像などを抜いたもの
- 旧題「行動してから主張せよ」
Python の unittest.mock
- 2008年に誕生
- Python 3.3 でビルトインに
- record -> replay より action -> assertion
record -> replay
# record
mocker = Mocker()
mock = mocker.mock()
mock.get("https://haskell.jp")
mocker.result(Response())
client = Client()
client.agent = mock
# replay
mocker.replay()
res = client.call_api("https://haskell.jp")
mocker.restore()
mocker.verify()
record -> replay
- テスト結果を先に記述する必要がある
- 動作後にも検証が必要なので、検証コードが分かれる
action -> assertion
client = Client()
client.agent = mock.Mock()
# action
res = client.call_api("https://haskell.jp")
# assertion
client.agent.get.assert_called_with("https://haskell.jp")
action -> assertion
- 動作させ、その結果を検証するという流れ
- 通常の単体テストの流れと合致する
Perlで実装したい
- unittest.mock の使い勝手が良かった
- CPANに類似モジュールがなさそう
LTのネタになりそう- 職場の "20%ルール" 的な制度を利用
- https://github.com/hiratara/p5-Test-LazyMock
テストしたいコード
sub test_code {
my $dbh = DBI->connect(
"DBI:mysql:yapc:localhost", "tokyo", "oykot");
my $sth = $dbh->prepare("SELECT name, age FROM atendee");
$sth->execute;
my $atendee = $sth->fetchrow_hashref;
printf "%s (%d)\n", $atendee->{name}, $atendee->{age};
}
テストコード
patch_sub {
my $mock = shift;
# action
test_code;
# assertion
$mock->lazymock_called_with_ok(
prepare => ["SELECT name, age FROM atendee"]);
} 'DBI::connect';
test_code
より以下が出力される。
Test::LazyMock=REF(0x7fea9f0f25b0) (1)
呼出履歴の表示
print "$_->[0]\n" for $mock->lazymock_calls;
prepare
prepare->execute
prepare->fetchrow_hashref
prepare->fetchrow_hashref->{name}
prepare->fetchrow_hashref->{name}->`""`
prepare->fetchrow_hashref->{age}
prepare->fetchrow_hashref->{age}->`0+`