Тестирование Ruby-модулей с помощью rspec
У меня плохое время найти в SO/Google этот конкретный случай. У меня есть модуль с функциями и для их использования вы должны создать класс, который включает/расширяет модуль в зависимости от того, нужны ли методы экземпляра или методы класса.
module A
def say_hello name
"hello #{name}"
end
def say_bye
"bye"
end
end
Как проверить этот модуль с помощью rspec?
У меня есть что-то вроде этого, и я не уверен, где именно я должен создать класс и расширить модуль.
describe A do
class MyClass
extend A
end
before(:each) { @name = "Radu" }
describe "#say_hello" do
it "should greet a name" do
expect(Myclass.say_hello(@name)).to eq "hello Radu"
end
end
end
Спасибо!
Ответы
Ответ 1
Вы можете создать анонимный класс в своих тестах:
describe A do
let(:extended_class) { Class.new { extend A } }
let(:including_class) { Class.new { include A } }
it "works" do
# do stuff with extended_class.say_hello
# do stuff with including_class.new.say_hello
end
end
Чтобы увидеть что-то подобное в реальном коде, я использовал эту стратегию для тестирования моего attr_extras lib.
Тем не менее, include
и extend
являются стандартными функциями Ruby, поэтому я не буду тестировать, что каждый модуль работает как при включении, так и при расширении - обычно это заданный.
Если вы создаете именованный класс в тесте, как и в своем вопросе, я считаю, что класс будет существовать глобально на протяжении всего вашего тестового прогона. Таким образом, этот класс будет протекать между каждым тестом вашего тестового набора, потенциально вызывающим конфликты где-то.
Если вы используете let
для создания анонимного класса, он будет доступен только в этом конкретном тесте. Не существует глобальной постоянной, указывающей на нее, которая может конфликтовать с другими тестами.
Ответ 2
Чтобы помочь будущим читателям, вот пример, который я получил, используя решение @henrik-n:
# slim_helpers.rb
module SlimHelpers
# resourceToTitle converts strings like 'AWS::AutoScaling::AutoScalingGroup'
# to 'Auto Scaling Group'
def resourceToTitle(input)
input.split('::')[-1].gsub(/([A-Z])/, ' \1').lstrip
end
end
# slim_helpers_spec.rb
require_relative '../slim_helpers'
describe SlimHelpers do
# extended class
let(:ec) { Class.new { extend SlimHelpers } }
it "converts AWS resource strings to titles" do
out = ec.resourceToTitle('AWS::AutoScaling::AutoScalingGroup')
expect(out).to eq 'Auto Scaling Group'
end
end