我正在模块“ 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
答案 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