ok_gntpdというTCPServerをつかったサーバを相手にしたテストを書いた時のメモ。
テストしたい内容としては
- サーバを立ちあげて、
- 特定の文字列を送信したときに
- 特定の文字列を受信する
ということ。規模的に結合テストというほどのものではないけど、サーバを外から叩いた結果をチェックしたいのでサーバは別スレッドで動作させることになる。
こんな感じ:
require "spec_helper" describe OkGntpd do specify do #== 1. サーバを立ちあげて、 # サーバのインスタンス作成 server = OkGntpd.new( # 空いてるポートを探すためのおまじない :port => TCPServer.open('127.0.0.1', 0) { |s| s.addr[1] } ) # サーバの起動を子スレッドで t = Thread.new(server) do |s| Thread.pass # 親スレッドにすぐ引き渡す s.start # サーバを起動開始(ただし親スレッドへの復帰とはズレるので、joinして待つ) end # サーバが起動するまで0.05秒間隔で親スレッドを止めてチェック t.join(0.05) until server.started? begin #== 2. 特定の文字列を書き込んだときに # ソケットを開いて書き込む sock = TCPSocket.open("127.0.0.1", server.options[:port]) sock.write <<EOS GNTP/1.0 REGISTER NONE\r Application-Name: ok_gntpd\r \r EOS #== 3. 特定の文字列を受信する # 書き込んだ結果を見てサーバがデータを送り返してくるので、それを読み込む response = sock.read response.should == <<EOS GNTP/1.0 -OK NONE\r \r EOS ensure sock.close t.exit # スレッドのクローズは忘れずに end end end
テストを書くためにわざわざ追加したメソッドがあって、それはOkGntpd#started?
というもの。別スレッドでサーバを動かすけども、それが起動したかどうか外から調べるために追加した。
テスト書くのは本体の実装よりも力量を求められる気がする。これまでスレッドとかソケットとかまともに触ってこなかったので、この量でも大変だった…。