模拟Thread中的对象方法?

时间:2010-02-10 14:27:00

标签: ruby rspec

在下面的情况下,@ crawl对象会收到抓取调用,但方法模拟失败,即:该方法未被模拟。

Thread是否以某种方式创建了自己的@crawl对象副本,以逃避模拟?

  @crawl.should_receive(:crawl).with(an_instance_of(String)).twice.and_return(nil)

  threads = @crawl.create_threads

线程创建代码:

  def crawl(uri)
    dosomecrawling
  end

  def create_threads
    (1..5).each do
      Thread.new do
        crawl(someurifeedingmethod)
      end
    end
  end

2 个答案:

答案 0 :(得分:2)

从发布的代码中看不出您正在加入线程。如果是这样,则存在竞争条件:有时候测试将执行部分或全部线程未完成其工作;修复方法如下:

!/usr/bin/ruby1.9

class Crawler

  def crawl(uri)
    dosomecrawling
  end

  def create_threads
    @threads = (1..5).collect do
      Thread.new do
        crawl(someurifeedingmethod)
      end
    end
  end

  def join
    @threads.each do |thread|
      thread.join
    end
  end

end

describe "the above code" do

  it "should crawl five times" do
    crawler = Crawler.new
    uri = "uri"
    crawler.should_receive(:someurifeedingmethod).with(no_args).exactly(5).times.and_return(uri)
    crawler.should_receive(:crawl).with(uri).exactly(5).times
    crawler.create_threads
    crawler.join
  end

end

答案 1 :(得分:0)

此代码完美无缺。

您可以添加预期的5倍。


class Hello
  def crawl(uri)
    puts uri 
  end 

  def create_threads
    (1..5).each do
      Thread.new do
        crawl('http://hello')
      end 
    end 
  end 
end

describe 'somting' do
  it 'should mock' do
    crawl = Hello.new
    5.times do
      crawl.should_receive(:crawl).with(an_instance_of(String)).and_return(nil)
    end                                                                                                                                   
    threads = crawl.create_threads
  end 
end