简体   繁体   English

RSpec be_equal无效

[英]RSpec be_equal not working

I am writing some rspec examples for a plain old ruby class in my rails project and I am facing the following problem. 我正在我的rails项目中为一个普通的旧ruby类编写一些rspec示例,我遇到了以下问题。 I have this constructor: 我有这个构造函数:

    class Server
        def initialize(host='localhost',options={:port => 443, :password => '', :vpncmd_bin_path => '/usr/local/bin/vpncmd', :timeout => 5})
            @host = host
            @port = options[:port].present? ? options[:port] : 443
            @password = options[:password].present? ? options[:password] : ''
            @vpncmd_bin_path = options[:vpncmd_bin_path].present? ? options[:vpncmd_bin_path] : '/usr/local/bin/vpncmd'
            @timeout = options[:timeout].present? ? options[:timeout] : 5
            @hubs = {}
            @hub_cache_dirty = true
            @hub_password_cache = {}
        end
        ...
    end

This test example: 这个测试例子:

  it "should have a default constructor that takes no argument" do
    s = SoftEther::Server.new()
    expect(s.host).to be_equal('localhost')
    expect(s.port).to be_equal('443')
    expect(s.timeout).to be_equal(5)
    expect(s.vpncmd_bin_path).to be_equal('/usr/local/bin/vpncmd')
    expect(s.password).to be_equal('')
  end

And rspec gives me the following result with Rails 4.2.6, jruby-9.0.5.0 and 3.4.4: 并且rspec在Rails 4.2.6,jruby-9.0.5.0和3.4.4中给出了以下结果:

  1) SoftEtherSever should have a default constructor that takes no argument
     Failure/Error: expect(s.host).to be_equal('localhost')
       expected `"localhost".equal?("localhost")` to return true, got false
     # ./spec/poro/softether_spec.rb:19:in `block in (root)'

What did I do wrong? 我做错了什么?

equal? checks whether two instances are the same. 检查两个实例是否相同。 But it returns false when two strings contains the same value but refers to different objects: 但是当两个字符串包含相同的值但引用不同的对象时,它返回false:

"foo".equals?("foo")
# => false

What you should really use is eq() 你应该真正使用的是eq()

expect(s.host).to eq('localhost')

Just to add an edge case to Simone's answer: 只是为Simone的答案添加一个边缘案例:

If you were to freeze the strings in question, you would get the result you expected: 如果你要冻结有问题的字符串,你会得到你期望的结果:

irb(main):001:0> 'test'.equal? 'test'
=> false
irb(main):002:0> 'test'.freeze.equal? 'test'.freeze
=> true

In Ruby 2.3, this can be done by adding 在Ruby 2.3中,这可以通过添加来完成

# frozen_string_literal: true

to the top of the Ruby file. 到Ruby文件的顶部。

With that said, Simone is right. 话虽如此,西蒙娜是对的。 You should use the eq matcher unless you truly want to test that you are using the same exact object instance. 您应该使用eq匹配器,除非您确实要测试您使用的是相同的对象实例。 Then using equal is in order. 然后使用equal的顺序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM