Rails:更好的方式编写测试用例以备关注

时间:2018-04-16 23:29:28

标签: ruby-on-rails rspec rspec-rails

我关注的代码如下:

module UserStatus
  extend ActiveSupport::Concern
  included do
    enum status: %i[not_started in_progress completed]
  end
end

我正在尝试为它编写一个rspec测试。

require 'rails_helper'

RSpec.describe 'user_status' do
  it 'test' do
    byebug
    should define_enum_for(:status).with(%i[not_started in_progress completed])
  end
end

上述情况会返回错误:

undefined method `defined_enums' for Module:Class

如果我删除should,它就会通过。但我不知道这是否是测试它的正确方法。还有更好的方法吗?

2 个答案:

答案 0 :(得分:0)

单词should不会去那里。你的规格看起来应该更像这样:

RSpec.describe 'user_status' do
  it 'should do something related to the user_status' do
    define_enum_for(:status).with(%i[not_started in_progress completed])
  end
end

当以这种方式书写时,您的规格正在讲述他们正在做什么的故事。文本的should do something位是对规范测试内容的简明英文描述,以及构成测试的实际Ruby代码之后的代码。

"普通英语"规范的一部分完全是为了让你能够理解该规范的目的是什么,以及使用“"”这个词应该"只是为了帮助你理解它。你可以在那里写任何东西,它不会影响实际的规格。另一种写作方式可能是:

it 'ensures the user_status is valid' do
  <whatever your ruby code is>
end

或者:

it 'renders the user_status view' do
  <whatever your ruby code is>
end

关键是,使普通英语文本与规范所做的一致,以便将来你可以回到那个规范并立即知道它正在测试什么而不必破译Ruby代码。

答案 1 :(得分:0)

您无法测试模块,您需要测试模型本身。所以你需要添加

it { should define_enum_for(:status).with(%i[not_started in_progress completed]) }

到型号规格。

如果您不想在包含问题的每个模型中重复此行,您可以写shared examples

# it is convenient to write in the separate file, e.g. 'spec/support/models/shared_examples_for_statusable.rb'
RSpec.shared_examples 'status_able' do 
  it { should define_enum_for(:status).with(%i[not_started in_progress completed]) }
end

require '/support/models/shared_examples_for_statusable.rb'
RSpec.describe SomeClass do
  it_behaves_like 'status_able'
end