test と mock と
試験のバックトレイスって勉強になるねぇ。以下の試験を元に色々検証。
def test_send_pings @article1.send_pings("example.com", "http://localhost/post/5?param=1") ping = Net::HTTP.pings.first assert_equal "localhost",ping.host assert_equal 80, ping.port assert_equal "/post/5?param=1", ping.query assert_equal "title=Article%201!&excerpt=body&url=example.com&blog_name=test%20blog", ping.post_data end
send_pings については昨晩のエントリでコード引用しているので略するが、引数に元記事の URL と trackback ping を送信したい記事の URL の配列が渡される (はず)。で、Ping のオブジェクトを作って、send_ping メソドを実行した後に DB に格納、という一連の処理となっている。
上記のコードはそれを試験するためのコード。
単体試験とゆー事で http なやりとりの mock も用意されていた。参考になる。
module Net remove_const "HTTP" class Request < Struct.new(:host, :port, :query, :post_data) def post(query, post) self.query = query self.post_data = post end end class Net::HTTP def self.start(host, port) request = Request.new request.host = host request.port = port @pings ||= [] @pings << request yield request end def self.pings @pings end end
とりあえず順を追って、試験のコードから何がどうなっているのか、と纏めておく。
- ArticleTest#test_send_pings から Article#send_pings 呼び出し。
- Article#send_pings では Ping オブジェクトを生成(url 属性に ping 送信先の URL を設定) し、Ping#send_ping を呼ぶ。
- uri と post するデータを適宜作成し、Net::HTTP.start 呼び出し。
- 上記の mock なコードに定義された start 実行。
- start に渡しているブロックの引数は request インスタンス
- start なブロック中にて http.post (実は request.post) を呼び出し。
- Request#post では渡された query と post をインスタンスに設定
- Article#send_pings から戻ってきたら pings (mock なコードにて定義) 呼び出し
- Request インスタンスに設定された値を assert_equal で確認
これはこれは、なかなか。