Websocketのテストするのに、Test::Mojoに挑戦してみた
テストコードがなかったので、テストの練習がてら書いてみた。
Mojoliciousのバージョンあげたら。json_message_likeというのが 生えていて滅茶苦茶便利っぽい。
後は、Redisデータベースを初期化したいんだけど。テスト機だから 初っ端で全部消しちゃえばいいかな。(なんか安直)
もう少し、テストを充実させていこうと思う。
use Mojo::Base -strict; use Test::More; use Test::Mojo; use utf8; # dokechinさん入室、お部屋のメンバも通知されること my $td = Test::Mojo->new('Chat::Web'); $td->websocket_ok('/hoge/echo') ->send_ok('name dokechin') ->message_ok() ->json_message_is( "/name" => "dokechin") ->json_message_like( "/hms" => qr/^\d\d:\d\d:\d\d$/) ->json_message_is( "/message" => '入室しました。') ->message_ok() ->json_message_is( "/names" => ["dokechin"]); # ロビーにhogeルーム開設通知 my $tl = Test::Mojo->new('Chat::Web'); $tl->websocket_ok('/notify') ->send_ok('rooms') ->message_ok() ->json_message_is( "/rooms/0" => {name => "hoge"}); # papixさん入室、、お部屋のメンバも通知されること my $tp = Test::Mojo->new('Chat::Web'); $tp->websocket_ok('/hoge/echo') ->send_ok('name papix') ->message_ok() ->json_message_is( "/name" => "papix") ->json_message_like( "/hms" => qr/^\d\d:\d\d:\d\d$/) ->json_message_is( "/message" => '入室しました。') ->message_ok() ->json_message_is( "/names" => ["dokechin","papix"]); # papixさん入室がdokechinさんに伝わる $td->message_ok() ->json_message_is( "/name" => "papix") ->json_message_like( "/hms" => qr/^\d\d:\d\d:\d\d$/) ->json_message_is( "/message" => '入室しました。'); done_testing();
しかし、大きな問題が・・・
1つのsendで、2つのメッセージを受けるんですが、 メッセージを受信する順番が一意に決まらない。どちらが 先にくるかは運次第。Test::Mojoを使ってうまいとこ これを解決しなくてはいけない。さぁ。どうするか・・・ 考えて、考えた末に出した方法は・・・
メッセージを長さでソートしてから、詰めなおして テストするという技を開発しました。
my $messages = sub { my ($t) = @_; my $m1 = $t->message_ok()->message; my $m2 = $t->message_ok()->message; my @sorted = sort { length($a) <=> length($b)} ($m1->[1],$m2->[1]); $t->message([text => $sorted[0]]); $t->json_message_is( "/names" => ["dokechin"]); $t->message([text => $sorted[1]]); $t->json_message_is( "/name" => "dokechin") ->json_message_like( "/hms" => qr/^\d\d:\d\d:\d\d$/) ->json_message_is( "/message" => '入室しました。'); }; $td->websocket_ok('/hoge/echo') ->send_ok('name dokechin') ->$messages();