2010-02-10 85 views
1

在下面的情況下@crawl對象會接收爬網調用,但方法模擬失敗,即:該方法沒有被模擬。嘲笑線程內的對象方法?

線程是否以某種方式創建自己的@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 

回答

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 
 
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