2014-01-13 41 views
0

我有一個測試,真實失敗自定義非活動記錄類我寫:的Rails + Rspec的:測試說變量的值是零,控制檯說,否則

測試:

describe "#xml_for_initial_request" do 

    it "calls the access_request method" do 
    ups_shipping = UpsShipping.new 
    ups_shipping.should_receive(:credentials) 
    ups_shipping.print_xml 
    end 


end 

控制檯:

Failures: 

     1) UpsShipping#xml_for_initial_request calls the access_request method 
     Failure/Error: ups_shipping.print_xml 
     NoMethodError: 
      undefined method `to_xml' for nil:NilClass #<-- FAILURE HERE 
     # ./app/models/ups_shipping.rb:14:in `print_xml' 
     # ./spec/models/ups_shipping_spec.rb:465:in `block (3 levels) in <top (required)>' 

    Finished in 0.45009 seconds 
    1 example, 1 failure 

這發生在這個模型中:

require 'net/https' 
    require 'uri' 

    class UpsShipping 
     attr_reader :products, :purchase 

     def initialize(options = {}) 
     @products = options.fetch(:products, []) 
     @purchase = options[:purchase] 
     end 

     def print_xml 
     xml = '' 
     xml << credentials.to_xml #<-- ERROR OCCURS HERE 
     return xml 
     end 

     def credentials #<-- CREDENTIALS COMES FROM HERE 
     { 
      "AccessLicenseNumber" => UPS_API["access_key"], 
      "UserId" => UPS_API["user_id"], 
      "Password" => UPS_API["password"] 
      } 
     end 

.... 

然而,當我嘗試這在控制檯在測試環境中它的工作原理:

Nets-Mac-Pro:myproject emai$ RAILS_ENV=test bundle exec rails c --sandbox 
    /Users/emai/.rvm/gems/[email protected]/gems/ruby-debug-ide-0.4.18/lib/ruby-debug-ide/command.rb:27: warning: already initialized constant DEF_OPTIONS 
    Loading test environment in sandbox (Rails 3.2.13) 
    Any modifications you make will be rolled back on exit 
    1.9.3p362 :001 > ups_shipping = UpsShipping.new 
    => #<UpsShipping:0x007feb0c974790 @products=[], @purchase=nil> 
    1.9.3p362 :002 > ups_shipping.print_xml 
    => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<hash>\n <AccessLicenseNumber>xxxxx</AccessLicenseNumber>\n <UserId>xxxx</UserId>\n <Password>xxx</Password>\n</hash>\n" 
    1.9.3p362 :003 > ups_shipping.credentials 
    => {"AccessLicenseNumber"=>"xxxx", "UserId"=>"xxxx", "Password"=>"xxxx"} 

這是怎麼回事???

回答

1

should_receive正在攔截方法調用而不是調用原始方法,並且默認情況下返回nil。添加電話到and_call_original

ups_shipping.should_receive(:credentials).and_call_original 
+0

哦,太棒了,我不知道。所以'should_receive'攔截參數方法並阻止它被調用? – Edmund

+1

正確。通常你正在做的是檢查一些昂貴的/外部的東西被調用,並嘲弄一個合理的回答:'thing.should_receive(:crazy_network_call).and_return(「yep it worked」)'。因此,默認情況下,它的行爲如下:'thing.should_receive(:launch_space_shuttle).and_return(nil)',這就是你所看到的。 –

+0

謝謝!我學到了東西 – Edmund