在Rails应用程序中测试gem

时间:2011-02-23 11:36:34

标签: ruby-on-rails ruby rspec gem

我正在尝试测试我的服务是否正确调用Anemone.crawl。我有以下代码:

spider_service.rb

class SpiderService < BaseService
  require 'anemone'
  attr_accessor :url
  def initialize(url)
    self.url = url
  end
  def crawl_site
    Anemone.crawl(url) do |anemone|
    end
  end
end

spider_service_spec.rb

require 'spec_helper'
require 'anemone'

describe SpiderService do
  describe "initialize" do
    let(:url) { mock("url") }

    subject { SpiderService.new(url) }

    it "should store the url in an instance variable" do
      subject.url.should == url
    end
  end

  describe "#crawl_site" do
    let(:spider_service) { mock("spider service") }
    let(:url) { mock("url") }

    before do
      SpiderService.stub(:new).and_return(spider_service)
      spider_service.stub(:crawl_site)
      Anemone.stub(:crawl).with(url)
    end

    subject { spider_service.crawl_site }

    it "should call Anemone.crawl with the url" do
      Anemone.should_receive(:crawl).with(url)
      subject
    end

  end
end

这是我得到的错误,而且无法理解,因为我可以在Rails控制台中调用该服务,当我提供有效的URL时,我会从Anemone获取数据:

Failures:

  1) SpiderService#crawl_site should call Anemone.crawl with the url
     Failure/Error: Anemone.should_receive(:crawl).with(url)
     (Anemone).crawl(#<RSpec::Mocks::Mock:0x82bdd454 @name="url">)
         expected: 1 time
         received: 0 times
     # ./spec/services/spider_service_spec.rb:28

请告诉我,我已经忘记了一些愚蠢的事情(我可以​​责怪缺少咖啡,而不是一般的无能!)

感谢您的时间,

GAV株系

1 个答案:

答案 0 :(得分:1)

您的主题调用您创建的模拟对象上的方法(mock(“spider_service”)),而不是真正的SpiderService对象。你还将模拟蜘蛛服务上的调用无效,所以在主题中调用它将什么也不做,因此测试失败的原因。

此外,您在SpiderService上存根新内容(尽管您从未调用它)以返回模拟对象。当您测试SpiderService时,您将希望拥有该类的实际实例,否则方法调用将不会像在类的实际实例上那样运行。

以下内容应达到您的目的:

describe "#crawl_site" do
  let(:spider_service) { SpiderService.new(url) }
  let(:url) { mock("url") }

  before do
    Anemone.stub(:crawl).with(url)
  end

  subject { spider_service.crawl_site }

  it "should call Anemone.crawl with the url" do
    Anemone.should_receive(:crawl).with(url)
    subject
  end

end

您可能还想在类定义之外移动require'anenome',以便在其他地方使用。