#ruby-on-rails #ruby #rspec
#ruby-on-rails #ruby #rspec
Вопрос:
Я пробовал несколько способов получения нужных мне данных в моих общих спецификациях, однако я всегда получаю неопределенные значения.
Я делаю что-то похожее на следующее:
require 'spec_helper'
describe UserAnalyticsService do
before(:each) { @user = FactoryGirl(:user) }
let(:user_query) { UserAnalyticsQuery.build(@user) }
let(:totals) { UserAnalyticsService.new(user_query) }
it_should_behave_like "an array of hashes" # What I want
end
Я пробовал следующее:
Вложенный let()
shared_examples "an array of hashes" do
it { expect(array).to be_an_instance_of(Array) }
it "each element should be an instance of Hash" do
array.each { |element| expect(element).to be_an_instance_of(Hash) }
end
end
И выполнение:
использование let()
it_should_behave_like "an array of hashes" do
let(:array) { totals.inactive_users }
end
использование переменной экземпляра
before(:each) { @array = totals.inactive_users }
Затем
it_should_behave_like "an array of hashes" do
let(:array) { @array }
end
Параметры блока
shared_examples "an array of hashes" do |array|
it { expect(array).to be_an_instance_of(Array) }
it "each element should be an instance of Hash" do
array.each { |element| expect(element).to be_an_instance_of(Hash) }
end
end
Затем
it_should_behave_like "an array of hashes", @array
Все следующее приводит к nil
исключениям указателей и неопределенным переменным.
Любые советы, предложения или рекомендации приветствуются, заранее спасибо.
Редактировать
Хорошо, итак, я углубился в let()
изучение и понимаю, что данные, переданные в общий пример, должны существовать до транзакционного блока.
Я почти уверен, что это была моя проблема, поскольку я использовал before(:each)
и let()
для передачи данных, однако они оба не определены, пока мы не дойдем до группы примеров.
Ввод по-прежнему очень приветствуется, особенно в отношении альтернатив или перспектив, которые помогут перенести эти общие спецификации в общий пример.
Ответ №1:
Должен признать, я был смущен использованием rspec shared_examples и отказался от них в последний раз, когда пытался с ними работать, но ваш вопрос вдохновил меня на другой взгляд.
Удивительно, но на самом деле это оказалось очень просто и не заняло слишком много времени, чтобы выполнить некоторые пройденные тесты — я либо упускаю что-то фундаментальное в вашем вопросе, либо следующее должно дать вам некоторый намек на то, что вам нужно сделать.
Сами тесты должны быть понятными:
require 'rails_helper'
RSpec.describe Array, type: :class do
shared_examples 'an array of hashes' do
it { expect(array).to be_an_instance_of(Array) }
it 'each element should be an instance of Hash' do
array.each { |element| expect(element).to be_an_instance_of(Hash) }
end
end
describe 'with an array of hashes' do
context 'with predefined array' do
let(:hash) { Hash.new(name: 'hash', value: 'value') }
let(:array) { [hash, hash, hash] }
context 'without using shared examples' do
it { expect(array).to be_an_instance_of(Array) }
it 'each element should be an instance of Hash' do
array.each { |element| expect(element).to be_an_instance_of(Hash) }
end
end
context 'using shared examples' do
it_should_behave_like 'an array of hashes'
end
end
context 'when passing array to shared example' do
let(:hash) { Hash.new(name: 'hash', value: 'value') }
let(:myarray) { [hash, hash, hash] }
it_should_behave_like 'an array of hashes' do
let(:array) { myarray }
end
context 'with use of before(:each) block' do
before(:each) do
@myarray = myarray
end
it_should_behave_like 'an array of hashes' do
let(:array) { @myarray }
end
end
end
end
end
Не должно быть причин, по которым следующее также не должно работать:
it_should_behave_like 'an array of hashes' do
let(:array) { totals.inactive_users }
end
Комментарии:
1. Привет, спасибо, что вернулись к этому! Теперь я понимаю, почему последний пример должен работать. Общий пример выполняется внутри транзакции,
let(:array)
вызывается внутри этой транзакции, затемlet(:total)
вызывается bylet(:array)
. Я не уверен, почему это не работало, но я помню, что это было не определено. Спасибо, что добавили еще один уровень понимания этой проблемы!