[rspec-users] Help needed

Jens Carroll lists at carroll.de
Sun May 18 13:29:12 EDT 2008


Jarkko Laine schrieb:
> Hi Jens,
>
> On 17.5.2008, at 20.34, Jens Carroll wrote:
>
>> Hi All,
>>
>> I am new to rspec and it seems that I don't understand some basics.
>> I need to have a XML import which should parse through XML data
>> and saves all that in various mysql tables. The XML part works just
>> fine and I can test this with rspec. However when I try to execute
>>
>> it "should find country object for DE" do
>>
>> I get an error. @user.country is a one-to-many relation in the user 
>> table. It seems easy but I don't get it (hmmmm feels like I am still 
>> a newbie).
>>
>> The error I get is:
>>
>> 'XmlImport should find country object for DE' FAILED
>> expected #<Country:0x..fdb71beba @name="Country_1001">, got nil 
>> (using .equal?)
>>
>>
>> Any help very appreciated.
>> Thanks
>> Jens
>>
>> --- model ---
>>
>> require 'hpricot'
>> class XmlImport #< ActiveRecord::Base
>>
>>  attr_reader :doc, :user
>>
>>  def parse_xml(file)
>>    @doc = Hpricot.XML(open(file))
>>
>>    (@doc/:member).each do |data|
>>      retrieve_and_save_user(data)
>>    end
>>  end
>>
>>  def retrieve_and_save_user(data)
>>    # email address must be unique for members
>>    @user = User.find_or_initialize_by_email(email)
>>
>>    # save user if not existing
>>    if @user.new_record?
>>      @user.country = 
>> Country.find_by_short((data/:countryShort).inner_html)
>>    end
>>  end
>> end
>>
>>
>> ---- spec -------
>>
>> module XmlImportSpecHelper
>>
>>  def mock_xml_import
>>    xml_file = RAILS_ROOT + "/spec/fixtures/import-member.xml"
>>    xml = File.read(xml_file)
>>
>>    @xml_import = XmlImport.new
>>    @xml_import.should_receive(:open).exactly(1).times.
>>      with("any-file-name.xml").
>>      and_return(xml)
>>  end
>>
>> end
>>
>> describe XmlImport do
>>
>>  include XmlImportSpecHelper
>>
>>  before(:each) do
>>    mock_xml_import
>>    @xml_import.parse_xml("any-file-name.xml")
>>
>>    @country = mock_model(Country)
>>    Country.stub!(:find_by_short).and_return(@country)
>
> In order to have the above stubbing and mocking work, it must be done 
> *before* you use them in the actual code. It seems to me that 
> parse_xml is where you want to use them.
>
>>
>>  end
>>
>>  it "should find country object for DE" do
>>    
>> Country.should_receive(:find_by_short).with("DE").and_return(@country)
>
> Same here. should_receive must always be defined before you run the 
> code that is expected to do something. In this case, parse_xml and 
> thus Country.find_by_short is run without any stubbing so it will go 
> to the database and probably find nothing.
>
>>
>>    @xml_import.user.country.should equal(@country)
>>  end
>> end
>> _______________________________________________
>> rspec-users mailing list
>> rspec-users at rubyforge.org
>> http://rubyforge.org/mailman/listinfo/rspec-users
>
> -- 
> Jarkko Laine
> http://jlaine.net
> http://dotherightthing.com
> http://www.railsecommerce.com
> http://odesign.fi
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users

Hi Jarkko,

Thanks a lot. The next time when I get a nil object I'd better ask 
myself if the mocking and stubbing
has been before the actual code. The real problem was that my whole 
rspec test got quite big. I need to break it down in smaller pieces not 
to lose the overview.

Have a nice day
Jens


More information about the rspec-users mailing list