16

我该怎么做:

it { should have_constant(:FIXED_LIST) }

在我的模型(活动记录)中,我有FIXED_LIST = 'A String'

它不是数据库属性或方法,我无法使用responds_tohas_attribute测试它(它们失败了)。我可以用什么来检查它。- 顺便说一句,我安装了应该匹配器。

4

8 回答 8

18

根据 David Chelimsky 的回答,我可以通过稍微修改他的代码来实现这一点。

在文件 spec/support/utilities.rb(或 spec/support 中的其他文件)中,您可以输入:

RSpec::Matchers.define :have_constant do |const|
  match do |owner|
    owner.const_defined?(const)
  end
end

注意使用“RSpec::Matchers.define”而不是“matchers”

这允许测试规范中的常量,例如:

 it "should have a fixed list constant" do
    YourModel.should have_constant(:FIXED_LIST)
 end

注意使用“have_constant”而不是“have_const”

于 2012-12-17T15:22:49.607 回答
10

它读起来有点傻,但是:

describe MyClass do

  it { should be_const_defined(:VERSION) }

end

原因是 Rspec 对以be_and开头的方法有“神奇的”匹配器have_。例如,it { should have_green_pants }将断言返回的has_green_pants?方法。subjecttrue

以同样的方式,一个例子it { should be_happy }会断言返回的happy?方法。subjecttrue

因此,该示例it { should be_const_defined(:VERSION) }断言const_defined?(:VERSION)返回true.

于 2013-04-16T23:41:09.130 回答
8

如果你想说have_constant你可以为它定义一个自定义匹配器:

matcher :have_constant do |const|
  match do |owner|
    owner.const_defined?(const)
  end
end

MyClass.should have_const(:CONST)

如果您尝试使用单行语法,则需要确保主题是类(而不是实例)或在匹配器中检查它:

matcher :have_constant do |const|
  match do |owner|
    (owner.is_a?(Class) ? owner : owner.class).const_defined?(const)
  end
end

有关自定义匹配器的更多信息,请参阅http://rubydoc.info/gems/rspec-expectations/RSpec/Matchers

HTH,大卫

于 2012-07-05T04:35:15.547 回答
4

另一种简单地确保定义常量的选项——不用担心它是用什么定义的:

it 'has a WHATEVER constant' do
  expect(SomeClass::WHATEVER).not_to be_nil
end
于 2019-03-25T20:10:25.023 回答
3

对尝试测试常量已定义的任何人的警告:如果您的代码在定义类时引用了未定义的常量,那么您的规范将在测试之前崩溃。

这会让你相信

expect { FOO }.to_not raise_error

未能捕获 NameError,因为您将得到一个很大的堆栈跟踪,而不是一个很好的“预计不会引发错误,但引发了 NameError”。

在巨大的堆栈跟踪中,很难注意到您的测试实际上在第 1 行崩溃:requre "spec/spec_helper" 因为您的整个应用程序在进入实际测试之前无法加载。

如果您有动态定义的常量,例如由 ActiveHash::Enum 完成,然后您在另一个常量的定义中使用它们,就会发生这种情况。不要费心测试它们是否存在,如果其中一个规范未能定义,您的应用程序中的每个规范都会崩溃。

于 2014-04-04T13:41:21.387 回答
1

你可以使用

defined? YOUR_MODEL::FIXED_LIST
于 2012-07-05T03:57:16.280 回答
1

在 RSpec 2 中,我能够让它在一行中工作,如下所示:

it { subject.class.should be_const_defined(:MY_CONST) }

也就是说,检查类,而不是实例。

于 2016-03-24T21:37:15.923 回答
0

在我的模型中

 class Role < ActiveRecord::Base
   ROLE_ADMIN = "Administrador"     
 end

在我的 rspec

 RSpec.describe Role, type: :model do
  let(:fake_class) { Class.new }

  describe "set constants" do
    before { stub_const("#{described_class}", fake_class) }

    it { expect(described_class::ROLE_ADMIN).to eq("Administrador") }
  end
end
于 2017-03-03T17:10:19.910 回答