ruby 如何避免每次在rspec中输入模块名?

4dbbbstv  于 2022-11-04  发布在  Ruby
关注(0)|答案(5)|浏览(173)

我正在测试我的模块'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
xu3bshqb

xu3bshqb1#

您可以使用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
j2qf4p5b

j2qf4p5b2#

长期以来,我只是说把它写出来。打字多一点,但阅读起来很容易。
话虽如此,我的建议是:
方法1:通过将模块赋给一个变量来缩短它

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

或者甚至进一步细化到单个嵌套类

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

match_found.new(...)

方法2:为每个常用的段将构造 Package 在一个helper方法中

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)}
332nm8kg

332nm8kg3#

您可以随时创建别名,非常简单:

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)

尽管需要进行更多的重构,但您可以通过应用名为 Don't Repeat Yourself 或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

试着从数据转换的Angular 来考虑Ruby程序,你通常可以从一些简单的东西开始,比如这个名字数组,然后一步一步地构建出你想要的结构。

wb1gzix0

wb1gzix04#

只是一个想法。而不是

RecipientMatcher::RecipientMatchFound

您可以使用

magic_resolver('RecipientMatchFound')

其中它被定义为RSec辅助器:

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

c3frrgcw5#

我今天在尝试解决同样的问题时遇到了这个问题(使用ruby 2.7.2和rspec v3.6.0)。我有一个带有Foo::Bar模块的gem,其中定义了gem的所有类,我不想在我的所有规范中输入Foo::Bar::前缀。
我尝试编辑spec_helper.rb:

RSpec.configure do |config|
  config.include Foo::Bar
  ...
end

但没有成功。
最后,添加

include Foo::Bar

spec_helper.rb * 以上 *

RSpec.configure do |config|
...

块允许我引用不带前缀的类,例如:

RSpec.describe Baz do; end

而不是

RSpec.describe Foo::Bar::Baz do; end

相关问题