#ruby #unit-testing #rspec #mixins #rspec3
#рубиновый #модульное тестирование #rspec #mixins #rspec3
Вопрос:
Цель:
Я хочу запустить базовый модульный тест RSpec для метода экземпляра mixin (модуля) с именем Debug. Ниже приведено содержимое файла Debug mixin:
Файл Mixin: ./mixins/debug.rb
module Debug
public
def class_info?
"#{self.class.name}"
end
end
Проверка методов экземпляра Debug mixin, доступных из RSpec:
Когда я запускаю irb
и включаю Debug mixin с помощью команд require_relative './mixins/debug.rb'
и include Debug
, а затем вызываю Debug.class_info?
его, он успешно возвращает "Module"
Затем, если я выполню rspec
следующий модульный тест RSpec, чтобы подтвердить, что контекст RSpec может получить доступ к методам экземпляра mixin, тест успешно пройден:
Настройка модульного тестирования RSpec # 1: ./spec/mixins/debug_spec.rb
require_relative '../../mixins/debug.rb'
RSpec.describe Debug, "#class_info?" do
include Debug
before(:each) do
@class_info_instance_method = Debug.instance_methods[0].to_s
end
context "with mixins" do
it "has class info instance method" do
expect(@class_info_instance_method).to eq "class_info?"
end
end
end
Проблема при вызове метода экземпляра Debug mixin из RSpec:
Наконец, я изменяю модульный тест RSpec следующим образом, поэтому вместо этого он фактически вызывает метод class_info?
экземпляра Debug mixin:
Настройка модульного тестирования RSpec # 2: ./spec/mixins/debug_spec.rb
require_relative '../../mixins/debug.rb'
RSpec.describe Debug, "#class_info?" do
include Debug
before(:each) do
@class_info = Debug.class_info?
end
context "with mixins" do
it "shows class info" do
expect(@class_info).to eq "Module"
end
end
end
Но теперь, когда я запускаю rspec
из командной строки, почему он возвращает следующую ошибку? (Примечание: несмотря на то, что в предыдущей настройке модульного тестирования RSpec # 1, которая была полностью аналогичной, я проверил, что могу успешно получить доступ к этому методу экземпляра Debug mixin)
1) Debug#class_info? with mixins shows class info
Failure/Error: @class_info = Debug.class_info?
NoMethodError:
undefined method `class_info?' for Debug:Module
Примечание: я поделился приведенным выше кодом в моем репозитории RubyTest на GitHub.
Настройка и рекомендации:
Моя система:
- Ruby: ruby 2.3.0p0 (
ruby -v
) - RSpec: 3.5.4 (
rspec -v
)
Ссылки:
- Применение примера из главы Mixins книги Programming Ruby
Ответ №1:
Когда вы включаете модуль, методы становятся методами экземпляра во включенном классе. Debug.class_info?
не работает, потому что нет метода класса class_info?
. Я также не уверен, что способ, которым вы включили модуль в свой тест, является лучшим способом сделать это. Сработает ли что-то подобное?
require_relative '../../mixins/debug.rb'
class TestClass
include Debug
end
RSpec.describe Debug, "#class_info?" do
let(:test_instance) { TestClass.new }
context "with mixins" do
it "shows class info" do
expect(test_instance.class_info?).to eq "TestClass"
end
end
end
Комментарии:
1. Я решаю свой первоначальный вопрос, перейдя
class_info?
наself.class_info?
. Но в вашем примереtest_instance.class_info?
вызывается метод экземпляра модуля отладки суперклассаclass_info?
. Поэтому я обновил модуль отладки двумя методами:def class_info?; Debug.class_info?; end
иdef self.class_info?; "#{self.class.name}"; end
. Чтобы ваш тест возвращал «TestClass» вместо «Module», я добавил переопределение для методаclass_info?
экземпляра в TestClass (т. Е.def class_info?; "#{self.class.name}" end
), чтобы он не вызывал метод экземпляра суперкласса