Как я могу избежать ввода имени модуля каждый раз в rspec? - PullRequest
0 голосов
/ 10 октября 2018

Я тестирую класс в моем модуле '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 голосов
/ 10 октября 2018

Вы всегда можете создать псевдоним, это действительно просто:

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 с точки зрения преобразования данных.Часто вы можете начать с чего-то простого, например, с массива имен, и постепенно построить структуры, которые вам нужны.

0 голосов
/ 10 октября 2018

Постоянно, я бы просто сказал, выпишите это.Немного больше печатать, но довольно легко читать.

Тем не менее, вот что я бы предложил:

Метод 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)}
0 голосов
/ 10 октября 2018

Вы можете использовать RSpec описаны_класс , при условии, что вы предоставите класс в качестве аргумента для основного блока describe, следующим образом:

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

В качестве альтернативы вы можете определить переменную (или let в RSpec) для класса, например, что-то вроде этого:

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

it 'whatever' do
  match_found.new(build(:group), match_object.new(...))
end
0 голосов
/ 10 октября 2018

Просто идея.Вместо

RecipientMatcher::RecipientMatchFound

вы можете использовать

magic_resolver('RecipientMatchFound')

, где он определен как помощник RSpec:

def magic_resolver(class_name)
  "RecipientMatcher::#{class_name}".constantize
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...