Help us understand the problem. What is going on with this article?

NokogiriをRspecでテストする。

Nokogiriに渡す引数をmock化してテストしたので残す。

FUGA_FUGA = ['企業', '秘密']
def hogegiri_method(fuga)
  HOGE_COUNT = 5
  HOGE_COUNT.times do |time|
    html = Nokogiri::HTML(OpenURI.open_uri(url))
    a, b, c = 正規表現わちゃわちゃ
    break if FUGAFUGA.include?(a)
  end
  { a: a, b: b, c: c }
end

色々見せられないコードなのでクソみたいなコードだが、、、今回mockとして偽物の戻り値を作りたいのが

html = Nokogiri::HTML(OpenURI.open_uri('内緒'))

ここ

だけどNokogiriの戻り値を直接and_returnで設定するのは難しい。

  • 戻り値がNokogiri::HTML::Documentといって単純なhtmlとかを返していない
  • method内部でnokogiri特有の戻り値にしか使えないmethodを使っている。

など

つまり、nokogiriには仕事をさせつつURLにはアクセスせず目的のデータを取らないといけない。

じゃ、どうするか

OpenUri.open_uri

こいつの戻り値をmock化してNokogiriの引数に渡すべき値を渡す。

Nokogiriの引数には解析したいHTMLがどうやら入るらしい。
それなら、本番環境ではアクセスして取ってくるURL先のHTMLをコピってhtmlfile作ってそこにペーストしてそいつを戻り値のmockにしてあげればいいのだ!!なんて簡単なことに記事づかなかったのだ。

ファイナルアンサー

spec/test.html
HTMLコピペ
allow(OpenURI).to receive(:open_uri).and_return(File.new("#{Rails.root}/spec/test.html"))

完成
これでまるでurlにアクセスして取ってきたように、methodが動作します。
さらに、and_returnの引数をnil,File.new("#{Rails.root}/spec/test.html")みたいにやると今回作ったmethodのロジックとして値を取得できなかったら最高5回はループするので、roopしていることも確認できますね。

インターン始めたから個人開発じゃ絶対しないようなことばっかしてるから毎回詰まりそうになるけど何とか教えてもらったり粘ったりしてガンバている

ちょっと成長したかも

mugioka
システム開発会社インターン中
https://twitter.com/m65136775
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away