その他
    ホーム技術発信DoRuby外部URLを偽装するテスト用ライブラリ「FakeWeb」

    外部URLを偽装するテスト用ライブラリ「FakeWeb」

    この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

    ご無沙汰しています。KBMJのプログラマのx5rです。

    最近、私が携わるプロジェクトでは、外部APIを利用したい、一部の機能を外出しにしてサービス間で連携したいという要望が徐々に増えつつあります。

    ただし、その外部システム(サービス、API)と連携する機能を実装はするものの、その機能をテストする場合、テストケース毎に毎回外部連携する訳にはいかないので、どうすればいいのかわかりませんでした。

    仮に、毎回そのシステムにリクエストを投げてテストするとしても、その外部システムも並行している開発する場合、そのシステムが出来上がるまで待っていなければなりません。

    みなさんこういった外部連携のテストをどうやって行っているのか調べていたところ、FakeWebというWebリクエストを偽装するgemライブラリがあることを知りました。

    そこで、今回はこのFakeWebというgemライブラリについて紹介したいと思います。

    インストール

    
    sudo gem install fakeweb
    

    サンプルプログラムとして、「みんな大好きgithub」ということで、先日Issue Tracker機能が追加され、また先日バージョンアップしたgithub APIを叩くプログラムを書いてみました。

    はい、私が試したかっただけです。。。

    github APIについて詳しくはDevelop.GitHubを参照してください。

    以下は、自分のアカウント名とリポジトリ名を引数として渡すとリポジトリ情報をYAML形式で取得するプログラムになります。

    試しに動作するか確認してみましょう。
    私のアカウント「mat5uda」にあるリポジトリ「dotfiles」の情報を取得してみましょう

    
    # github_api.rbのディレクトリで
    $ irb
    irb(main):001:0> require 'github_api'
    => true
    irb(main):002:0> GitHubApi.new.repository('mat5uda', 'dotfiles')
    => {"repository"=>{:owner=>"mat5uda", :homepage=>"http://matsuda.wordpress.com/", :name=>"dotfiles", :private=>false, :fork=>false, :forks=>0, :description=>"My configuration files", :url=>"http://github.com/mat5uda/dotfiles", :watchers=>1}}
    

    うまく取得できることが確認できました。

    さて、それでは本題のテストを書いてみます。

    最近はRSpecを利用するのが流行のようですが、自分の携わっているのはTestUnitなので、これを利用します。

    ※ github_api.rbとgithub_api_test.rbは同じディレクとにあるとします。

    ・使い方

    
    FakeWeb.register_uri(:get, "http://github.com/api/v2/yaml/repos/show/foo/hoge", :string => response)
    

    という箇所がrequestを偽装している処理になります。

    
    FakeWeb.register_uri(method, uri, options)
    

    のmethodにHTTPメソッド、uriに偽装するURI、optionsに:stringキーでレスポンスとして期待する値を渡します。

    その他のoptions指定や詳しい使い方はFakeWeb API Documentationを参照してください。

    では実際にテストする前に、テストで使用するアカウント「foo」にあるリポジトリ「hoge」を実際に確認してみます。

    
    $ irb
    irb(main):001:0> require 'github_api'
    => true
    irb(main):002:0> GitHubApi.new.repository("foo", "hoge")
    => {"error"=>[{"error"=>"repository not found"}]}
    

    実際には存在しないので、該当なしという結果が返ってきます。

    では、テストを実行してみましょう。

    
    $ ruby github_api_test.rb 
    Loaded suite github_api_test
    Started
    .
    Finished in 0.001169 seconds.
    
    1 tests, 4 assertions, 0 failures, 0 errors
    

    期待したとおりにテストが通りました。

    このように、もし連携先のシステムがまだ(実装中などで)存在しない場合で、そのシステムにHTTPアクセスするような機能のテストでは、スタブとしてFakeWebを利用することで、その機能自体のテストができるようになるので、利用してみてはどうでしょうか?