Rails + Rspec:测试说变量的值是nil,控制台说不然

时间:2014-01-13 20:00:07

标签: ruby-on-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/ruby-1.9.3-p362@myproject/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 个答案:

答案 0 :(得分:1)

should_receive正在拦截方法调用而不是调用原始函数,默认情况下会返回nil。添加对and_call_original的调用:

ups_shipping.should_receive(:credentials).and_call_original