0

我有以下代码:

  url       = "http://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Dpets&field-keywords="
  data      = Nokogiri::HTML(open(url))

  department   = data.css('#ref_2619534011')

  @department_hash = {}
  department.css('li').drop(1).each do | department |
    department_title = department.css('.refinementLink').text
    department_count = department.css('.narrowValue').text[/[\d,]+/].delete(",").to_i
    @department_hash[:department] ||= {}
    @department_hash[:department]["Pet Supplies"] ||= {}
    @department_hash[:department]["Pet Supplies"][department_title] = department_count
  end 

因此,当我<%= @department_hash %>在模板中执行此操作时,我会得到:

{:department=>{"Pet Supplies"=>{"Birds"=>15918, "Cats"=>245418, "Dogs"=>513869, "Fish & Aquatic Pets"=>47182, "Horses"=>14774, "Insects"=>358, "Reptiles & Amphibians"=>5834, "Small Animals"=>19806}}} 

app.rb我为(我正在使用 Sinatra)创建了一个规范:

app_spec.rb:

require File.dirname(__FILE__) + '/app.rb'

describe "Department" do
  it "should scrap correct string" do
    expect(@department_hash).to eq '{:department=>{"Pet Supplies"=>{"Birds"=>15918, "Cats"=>245418, "Dogs"=>513869, "Fish & Aquatic Pets"=>47182, "Horses"=>14774, "Insects"=>358, "Reptiles & Amphibians"=>5834, "Small Animals"=>19806}}}' 
  end
end

但测试失败:

  1) Department should scrap correct string
     Failure/Error: expect(@department_hash).to eq '{:department=>{"Pet Supplies"=>{"Birds"=>15918, "Cats"=>245418, "Dogs"=>513869, "Fish & Aquatic Pets"=>47182, "Horses"=>14774, "Insects"=>358, "Reptiles & Amphibians"=>5834, "Small Animals"=>19806}}}'

       expected: "{:department=>{\"Pet Supplies\"=>{\"Birds\"=>15918, \"Cats\"=>245418, \"Dogs\"=>513869, \"Fish & Aquatic Pets\"=>47182, \"Horses\"=>14774, \"Insects\"=>358, \"Reptiles & Amphibians\"=>5834, \"Small Animals\"=>19806}}}"
            got: nil

       (compared using ==)
     # ./app_spec.rb:5:in `block (2 levels) in <top (required)>'

编辑:

我试过这个:

expect(@department_hash[:department]["Pet Supplies"].keys).to eq '["Birds", "Cats", "Dogs", "Fish & Aquatic Pets", "Horses", "Insects", "爬行动物和两栖动物”、“小动物”]'

但测试也失败了:

2) 部门应该废弃正确的键失败/错误:expect(@department_hash[:department]["Pet Supplies"].keys).to eq '["Birds", "Cats", "Dogs", "Fish & Aquatic Pets ", "马", "昆虫", "爬行动物和两栖动物", "小动物"]' NoMethodError: undefined method []' for nil:NilClass # ./app_spec.rb:9:inblock (2 levels) in '

可能是什么原因?

4

1 回答 1

1

@department_hash未定义在测试范围内。

如果你举一个简单的例子:

require 'rspec/autorun'

@department_hash = 2
puts defined?(@department_hash)
#=> "instance-variable"

describe "Department" do
  it "should scrap correct string" do
        puts defined?(@department_hash)
        #=> "" (ie not defined)
    end
end

您可以看到@department_hash在 main 中定义,但在测试中未定义。

您需要在测试范围内运行您的应用程序代码。例如,将代码移动到测试中,@department_hash将不再为零。

require 'rspec/autorun'
require 'nokogiri'
require 'open-uri'

describe "Department" do
  it "should scrap correct string" do
    url       = "http://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Dpets&field-keywords="
    data      = Nokogiri::HTML(open(url))

    department   = data.css('#ref_2619534011')

    @department_hash = {}
    department.css('li').drop(1).each do | department |
      department_title = department.css('.refinementLink').text
      department_count = department.css('.narrowValue').text[/[\d,]+/].delete(",").to_i
      @department_hash[:department] ||= {}
      @department_hash[:department]["Pet Supplies"] ||= {}
      @department_hash[:department]["Pet Supplies"][department_title] = department_count
    end       

    expect(@department_hash).to eq({:department=>{"Pet Supplies"=>{"Birds"=>17556, "Cats"=>245692, "Dogs"=>516246, "Fish & Aquatic Pets"=>47424, "Horses"=>15062, "Insects"=>358, "Reptiles & Amphibians"=>5835, "Small Animals"=>19836}}})
  end
end

请注意,您的测试应该是eq(hash)而不是eq 'hash'(即您想要将哈希而不是字符串与哈希进行比较。

更新- 提取到类的代码:

如果将应用程序代码移到测试中是为了在其他地方可重用,那么它并不理想。相反,最好为您的应用程序代码创建一个方法或类,然后从测试中调用该代码。

require 'rspec/autorun'
require 'nokogiri'
require 'open-uri'

# This class could be placed in your app.rb  
class DepartmentScraper
  def scrape_page()
    url       = "http://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Dpets&field-keywords="
    data      = Nokogiri::HTML(open(url))

    department   = data.css('#ref_2619534011')

    @department_hash = {}
    department.css('li').drop(1).each do | department |
      department_title = department.css('.refinementLink').text
      department_count = department.css('.narrowValue').text[/[\d,]+/].delete(",").to_i
      @department_hash[:department] ||= {}
      @department_hash[:department]["Pet Supplies"] ||= {}
      @department_hash[:department]["Pet Supplies"][department_title] = department_count        
    end

    return @department_hash
  end
end

describe "Department" do
  it "should scrap correct string" do
    department_hash = DepartmentScraper.new.scrape_page()

    expect(department_hash).to eq({:department=>{"Pet Supplies"=>{"Birds"=>17556, "Cats"=>245692, "Dogs"=>516246, "Fish & Aquatic Pets"=>47424, "Horses"=>15062, "Insects"=>358, "Reptiles & Amphibians"=>5835, "Small Animals"=>19836}}})
  end
end
于 2013-08-15T12:49:25.847 回答