Reputation: 55343
I have the following code:
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
So when I do this <%= @department_hash %>
in a template I get this:
{:department=>{"Pet Supplies"=>{"Birds"=>15918, "Cats"=>245418, "Dogs"=>513869, "Fish & Aquatic Pets"=>47182, "Horses"=>14774, "Insects"=>358, "Reptiles & Amphibians"=>5834, "Small Animals"=>19806}}}
I created a spec for app.rb
(I'm using 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
But the test fails:
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)>'
EDIT:
I tried this:
expect(@department_hash[:department]["Pet Supplies"].keys).to eq '["Birds", "Cats", "Dogs", "Fish & Aquatic Pets", "Horses", "Insects", "Reptiles & Amphibians", "Small Animals"]'
But test fails also:
2) Department should scrap correct keys Failure/Error: expect(@department_hash[:department]["Pet Supplies"].keys).to eq '["Birds", "Cats", "Dogs", "Fish & Aquatic Pets", "Horses", "Insects", "Reptiles & Amphibians", "Small Animals"]' NoMethodError: undefined method
[]' for nil:NilClass # ./app_spec.rb:9:in
block (2 levels) in '
What could be the reason?
Upvotes: 0
Views: 186
Reputation: 46846
@department_hash
is not defined within the scope of the test.
If you take a simple example:
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
You can see that @department_hash
is defined in the main, but it is not defined within the test.
You need to run your app code from within the scope of the test. For example, moving the code into the test, @department_hash
will no longer be nil.
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
Note that your test should be eq(hash)
rather than eq 'hash'
(ie you want to compare hashes rather than a string to a hash.
Update - Code Extracted to a Class:
Moving the app code into the test is not ideal if it is meant to be reusable else where. Instead, it might be better to create a method or class for your application code and then call that code from the test.
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
Upvotes: 1