From: UEDA Hiroyuki Date: 2017-12-09T21:44:58+09:00 Subject: [ruby-list:50617] Kernel.open の stub 方法 うえだ と申します。 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}&key=#{API_KEY}&include=relations&offset=#{offset}&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