19

Mechanize を使用してサイトを走査する小さなプログラムを作成しました。

テストを書きたいのですが、テストを実行するたびに実際にサイトにログオンしたくありません。インターネットをモックして、あるサイトにアクセスしたときに、保存された結果を返すだけにしたいと思います。

ここに小さな例があります。私のコードの目的は、Google ホームページからリンクを引き出すことだったので、コードが見つけた最初のリンクに「画像」というテキストが含まれていることを確認するテストを作成します。私は次のように書くかもしれません:

require 'rubygems'
require 'mechanize'
require 'test/unit'

def my_code_to_find_links
  google = WWW::Mechanize.new.get('http://www.google.com')
  # ...
  # some code to figure out which links it wants
  # ...
  google.links
end

class TestGoogle < Test::Unit::TestCase
  def test_first_link_is_images
    assert_equal 'Images' , my_code_to_find_links.first.text
  end
end

実際にインターネットにアクセスするオーバーヘッドなしで my_code_to_find_links をテストできるように、google.com をモックするにはどうすればよいですか?

ありがとう -ジョシュ

4

4 に答える 4

36

Fakeweb を使用して、インターネットの応答をスタブ化します。

Google の例では、まず Web サイトにアクセスし、目的のページの html を保存します。この場合、ブラウザまたは curl で www.google.com を保存したとします。Fakeweb gem を test.rb ファイルに追加します

次に、あなたのコードは

stream = File.read("saved_google_page.html")
FakeWeb.register_uri(:get, 
    "http://www.google.com", 
    :body => stream, 
    :content_type => "text/html")

標準の Mechanize 呼び出しを行うと、

agent = Mechanize.New
page = agent.get("http://www.google.com/")

Fakeweb は、mechanize がインターネットに正常にアクセスしたと見なす方法で content_type ヘッダーを設定して保存したページを返します。content_type ヘッダーが設定されていることを確認してください。設定されていない場合、Mechanize はレスポンスを Mechanize::Page ではなく Mechanize::File として扱います。ネットワーク接続を外したマシンでテストを実行することにより、完全に機能していることをテストできます。

ps これは Google でのトップの結果ですが、未回答であるため、質問が出されてから 6 か月後に回答しています。私はこれを自分で理解するのに30分を費やし、解決策を共有したいと思いました.

于 2010-07-21T00:00:45.223 に答える
2

単体テストを作成している場合、スティックの間違った端を見ています。google.com をモックする必要はありませんが、Mechanize オブジェクトをモック/スタブする必要があります。mechanize オブジェクトが作成され、パラメーターhttp://www.google.comを使用してオブジェクトで get メソッドが呼び出されます。はい、スタブ応答で簡単に実行できるページにアクセスして、すべてのテストを実行することにより、取得した結果に対して実行している操作をテストする必要があります。たとえば、モカを使用している場合、

mechanize = stub('WWW::Mechanize')
WWW::Mechanize.stubs(:new).returns(mechanize)
mechanize.stubs(:get).with('http://www.google.com').returns('What ever out put you are expecting so that you can test')

Mechanize gem で既にテストされているため、リクエストが google.com に送信されるかどうかを実際にテストする必要はないと思います。

別の注意点として、統合/キュウリのテストを行っている場合は、sinatra を使用してサイトを偽造できます。Sinatra を使用すると、単一ページのスクリプトを作成し、そのスクリプトを Web サイトとして実行することが非常に簡単になります。

編集:

mochaを使用していない場合は、インストールしてテストでrequireする必要があります

sudo gem install mocha

そしてあなたのテストで

require 'rubygems'
require 'mocha'
于 2010-01-28T07:36:44.577 に答える
2

機能テストを作成していて、サーバーが特別なものである必要がない場合は、テストのためだけに実行される小さな HTTP サーバーを作成できます。テスト コードは、テスト対象のコードが localhost:<some_ephemeral_port> 上の小さな HTTP サーバーに接続するように構成します。

WEBrickをお勧めします。HTTP サーバーの設置は簡単です。

于 2010-01-28T04:28:10.230 に答える