【问题标题】:Pure Ruby rspec test passes without method being defined纯 Ruby rspec 测试通过而没有定义方法
【发布时间】:2014-05-20 09:34:21
【问题描述】:

我对纯 Ruby 模型进行了 rspec 测试:

require 'spec_helper'
require 'organization'

describe Organization do
  context '#is_root?' do
    it "creates a root organization" do
      org = Organization.new

      expect { org.is_root?.to eq true }
    end
 end
end

我的组织模型如下所示:

class Organization
  attr_accessor :parent

  def initialize(parent = nil)
    self.parent = parent
 end
end

运行测试时的输出:

bundle exec rspec spec/organization_spec.rb:6
Run options: include {:locations=>{"./spec/organization_spec.rb"=>[6]}}
.

Finished in 0.00051 seconds
1 example, 0 failures

当我运行测试时,它通过了,尽管方法 is_root?模型上不存在。我通常在 Rails 中工作,而不是纯 Ruby,而且我从未见过这种情况发生。怎么回事?

谢谢!

【问题讨论】:

  • 你可以在终端运行测试后发布输出
  • 您也可以发起rails console 并询问o.methods.select do |m| m.match /root/ end 以验证您对is_root? 的假设
  • 显然它在 expect{} 内进行了测试。当我放 org.method(:is_root?) 我失败了:1) Organization#is_root? creates a root organization Failure/Error: org.method(:is_root?) NameError: undefined method is_root?'对于类Organization' # ./spec/organization_spec.rb:10:in method' # ./spec/organization_spec.rb:10:in block (3 levels) in <top (required)>'
  • Patru,因为这不是 Rails 应用程序,而是纯 Ruby,所以没有可用的 Rails 控制台。

标签: ruby rspec


【解决方案1】:

应该是:

expect(org.is_root?).to eq true

当您将块传递给expect 时,它被包装在ExpectationTarget 类中(严格来说是BlockExpectationTarget < ExpectationTarget)。由于您没有指定对该对象的期望,因此该块永远不会执行,因此不会引发错误。

【讨论】:

    【解决方案2】:

    你正在传递一个期望的块,它永远不会被调用。您可以通过在该块上设置期望来看到这一点

    expect { org.is_root?.to eq true }.to_not raise_error
    
      1) Organization#is_root? creates a root organization
         Failure/Error: expect { puts "HI";org.is_root?.to eq true }.to_not raise_error
           expected no Exception, got #<NoMethodError: undefined method `is_root?' for #<Organization:0x007ffa798c2ed8 @parent=nil>> with backtrace:
             # ./test_spec.rb:15:in `block (4 levels) in <top (required)>'
             # ./test_spec.rb:15:in `block (3 levels) in <top (required)>'
         # ./test_spec.rb:15:in `block (3 levels) in <top (required)>'
    

    或者只是在块内放一个普通的 raise 或 puts,两者都不会被调用:

    expect { puts "HI"; raise; org.is_root?.to eq true }
    

    块形式用于预期一段代码是否引发异常。检查值的正确语法是:

    expect(org.is_root?).to eq(true)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-23
      • 1970-01-01
      • 1970-01-01
      • 2019-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多