[ruby-list:50618] Re: Kernel.open の stub 方法

From: UEDA Hiroyuki <bsdmad@...>
Date: 2017-12-11 11:04:41 UTC
List: ruby-list #50618
うえだと申します。

webmock という gem で私のやりたいことが実現できましたので、
今回はコレでいこうと思います。同じようなライブラリを複数、
使うのはちょっと妙な気もしますが…


以上です。



2017-12-09 21:40 GMT+09:00 UEDA Hiroyuki <bsdmad@gmail.com>:
> うえだ と申します。
>
> Rails で Redmine からチケットを一括取得して処理するコードを書いています。
> 動作自体は想定通りなのですが、これをテストすべく mocha を使って Kernel の
> open メソッドを stub 化してみたものの、自分が思ったようになりません。
>
> コードは以下のようになっています(抜粋です)。
>
>
> ---------- lib/interfaces/redmine/base.rb ----------
> # coding: utf-8
> #
> require 'open-uri'
> require 'net/http'
> require 'json'
> require 'date'
>
> module Interfaces
>   module Redmine
>     class Base
>
>       def self.search(uri, target, offset = -100, limit = 100)
>         list        = []
>         total       = nil
>         max_threads = 8
>         threads     = []
>         m           = Mutex.new
>
>         max_threads.times do |num_thread|
>           threads << Thread.start(num_thread) do |i|
>             while true
>               m.synchronize { offset += limit }
>               break if total && offset > total
>
>               open("#{URL}/#{uri}&amp;key=#{API_KEY}&amp;include=relations&amp;offset=#{offset}&amp;limit=#{limit}")
> { |io|
>                 data = JSON.parse(io.read)
>                 list << data[target]
>                 total = data["total_count"]
>               }
>               raise "Too many threads" if offset > 999999
>             end
>           end
>         end
>         threads.each {|th| th.join}
>
>         list.flatten
>       end
>     end
>   end
> end
> -------------------------------------------------------------------------
>
> ---------- test/lib/interfaces/redmine/base_test.rb ----------
> # coding: utf-8
> require 'test_helper'
>
> class RedmineBaseTest < ActiveSupport::TestCase
>   test 'should search correclty' do
>     data = {total_count: 10, issues: %w(a b c d e f g h i j)}.to_json
>     OpenURI.stubs(:open_uri).returns(StringIO.new(data))
>
>     puts data
>
>     assert_equal data['issues'],
> Interfaces::Redmine::Base.search('/projects/test', 'issues')
>   end
> end
> -------------------------------------------------------------------------
>
> これを実行すると、stub によって実際の Redmine サーバへのアクセスは
> 行われないものの、open した結果が何も返ってこないために exception が
> raise されてしまいます。
>
> $ bin/rake test TEST="test/lib/interfaces/redmine/base_test.rb"
> Running via Spring preloader in process 51657
> Loaded suite test
> Started
> .........................................{"total_count":10,"issues":["a","b","c","d","e","f","g","h","i","j"]}
> E
> ====================================================================================================
> Error: test: should search correclty(RedmineBaseTest): RuntimeError:
> Too many threads
> /path/to/project/lib/interfaces/redmine/base.rb:37:in `block (2
> levels) in search'
> ====================================================================================================
> ........................................................................
>
>
> お分かりになるがいらっしゃいましたら、私が想定しているテストケースを
> パスさせるような stub の書き方(の問題でしょうか…?)をご教示いただ
> ければ幸いです。
>
>
> どうぞよろしくお願いいたします。
>
> --
> UEDA "BSD mad" Hiroyuki <bsdmad@gmail.com>



-- 
UEDA "BSD mad" Hiroyuki <bsdmad@gmail.com>

In This Thread

Prev Next