如何避免每次在rspec中键入模块名称?

时间:2018-10-10 16:39:39

标签: ruby

我正在模块“ RecipientMatcher”中测试一个类。

必须在我所有班级的前面继续输入开头的名称“ RecipientMatcher”,这非常麻烦。我想知道是否有更好的方法?

今天的代码:

ocr_text = 'Jim Baker & Co'
recipient_matches = [
RecipientMatcher::RecipientMatchFound.new(build(:group), RecipientMatcher::MatchObject.new(nil,'Jim'), ocr_text, ocr_text.match(/Jim/)),
RecipientMatcher::RecipientMatchFound.new(build(:group), RecipientMatcher::MatchObject.new(nil, 'Jim Baker & Co'), ocr_text, ocr_text.match(/Jim Baker & Co/)),
RecipientMatcher::RecipientMatchFound.new(build(:group), RecipientMatcher::MatchObject.new(nil, 'Jim Baker'), ocr_text, ocr_text.match(/Jim Baker/)),
]

section_meta_data = RecipientMatcher::PossibleRecipientsCalculator.determine_primary_recipients_in_section(recipient_matches)
primary_recipients = section_meta_data.primary_recipients

expect(true).to eq(true)

如果我能写这样的话,那将是理想的:

RecipientMatcher.magic_method do
    ocr_text = 'Jim Baker & Co'
    recipient_matches = [
    ::RecipientMatchFound.new(build(:group), ::MatchObject.new(nil,'Jim'), ocr_text, ocr_text.match(/Jim/)),
    ::RecipientMatchFound.new(build(:group), ::MatchObject.new(nil, 'Jim Baker & Co'), ocr_text, ocr_text.match(/Jim Baker & Co/)),
    ::RecipientMatchFound.new(build(:group), ::MatchObject.new(nil, 'Jim Baker'), ocr_text, ocr_text.match(/Jim Baker/)),
    ]

    section_meta_data = ::PossibleRecipientsCalculator.determine_primary_recipients_in_section(recipient_matches)
    primary_recipients = section_meta_data.primary_recipients

    expect(true).to eq(true)
end

4 个答案:

答案 0 :(得分:2)

我每年都会说出来。多一点打字但很容易阅读。

也就是说,这是我的建议:

方法1:通过将模块分配给变量来缩短它

rm = RecipientMatcher
rm::RecipientMatchFound.new(...)
...

甚至更深入到单个嵌套类

match_found = RecipientMatcher::RecipientNotFound
match_obj = RecipientMatcher::MatchObject

match_found.new(...)

方法2:针对每个常用片段,将结构包裹在辅助方法中

def build_match(str)
  RecipientMatcher::RecipientMatchFound.new(build(:group), RecipientMatcher::MatchObject.new(nil,str), ocr_text, ocr_text.match(/#{str}/))
end

recipient_matches = [
  build_match('Jim'),
  build_match(...),
  ...
]

或循环

recipient_matches = ['Jim', 'Baker & Co', ...].map{|str| build_match(str)}

答案 1 :(得分:2)

您可以使用RSpec的described_class,只要您将类作为主describe块的参数提供即可,如下所示:

RSpec.describe RecipientMatcher::RecipientMatchFound do
  it 'whatever' do
    described_class.new(...)
  end
end

或者,您可以为该类定义一个变量(或RSpec中的let),例如像这样的东西:

let(:match_found) { RecipientMatcher::RecipientMatchFound }
let(:match_object) { RecipientMatcher::MatchObject }

it 'whatever' do
  match_found.new(build(:group), match_object.new(...))
end

答案 2 :(得分:1)

您始终可以创建一个别名,这非常简单:

RecipientMatchFound = RecipientMatcher::RecipientMatchFound
MatchObject = RecipientMatcher::MatchObject

ocr_text = 'Jim Baker & Co'
recipient_matches = [
  RecipientMatchFound.new(build(:group), MatchObject.new(nil,'Jim'), ocr_text, ocr_text.match(/Jim/)),
  RecipientMatchFound.new(build(:group), MatchObject.new(nil, 'Jim Baker & Co'), ocr_text, ocr_text.match(/Jim Baker & Co/)),
  RecipientMatchFound.new(build(:group), MatchObject.new(nil, 'Jim Baker'), ocr_text, ocr_text.match(/Jim Baker/)),
]

section_meta_data = RecipientMatcher::PossibleRecipientsCalculator.determine_primary_recipients_in_section(recipient_matches)
primary_recipients = section_meta_data.primary_recipients

expect(true).to eq(true)

尽管重构程度更高,但您可以通过应用称为不要重复自己或DRY:

recipient_matches = [
  'Jim',
  'Jim Baker & Co',
  'Jim Baker'
].map do |name|
  RecipientMatchFound.new(
    build(:group),
    MatchObject.new(nil, name), ocr_text, ocr_text.match(name)
  )
end

尝试并考虑数据转换方面的Ruby程序。您通常可以从简单的名称开始,例如此名称数组,并逐步构建出您想要的结构。

答案 3 :(得分:0)

只是个主意。代替

RecipientMatcher::RecipientMatchFound

您可以使用

magic_resolver('RecipientMatchFound')

它被定义为RSpec帮助器:

def magic_resolver(class_name)
  "RecipientMatcher::#{class_name}".constantize
end