Rspec разрешил обзор
Я считаю, что у меня проблема с rspec let и scoping. Я могу использовать методы, определенные с let в примерах (блоки "it" ), но не снаружи (блок описания, где я сделал let).
5 describe Connection do
8 let(:connection) { described_class.new(connection_settings) }
9
10 it_behaves_like "any connection", connection
24 end
Когда я пытаюсь запустить эту спецификацию, я получаю ошибку:
connection_spec.rb: 10: undefined local переменная или метод `connection 'для Класс: 0xae8e5b8 (NameError)
Как передать параметр соединения в it_behaves_like?
Ответы
Ответ 1
Я нашел, что работает для меня:
describe Connection do
it_behaves_like "any connection", new.connection
# new.connection: because we're in the class context
# and let creates method in the instance context,
# instantiate a instance of whatever we're in
end
Ответ 2
let() предполагается привязанным к примерам блоков и непригодным для использования в другом месте. Фактически вы не используете let() в качестве параметров. Причина, по которой он не работает с it_behaves_like как параметр, связан с определением let(). Каждая группа примеров в Rspec определяет собственный класс. let() определяет метод экземпляра в этом классе. Однако, когда вы вызываете it_behaves_like в этом пользовательском классе, он вызывается на уровне класса, а не из экземпляра.
Я использовал let() следующим образом:
shared_examples_for 'any connection' do
it 'should have valid connection' do
connection.valid?
end
end
describe Connection do
let(:connection) { Connection.new(settings) }
let(:settings) { { :blah => :foo } }
it_behaves_like 'any connection'
end
Я сделал что-то похожее на ответ bcobb, хотя я редко использую shared_examples:
module SpecHelpers
module Connection
extend ActiveSupport::Concern
included do
let(:connection) { raise "You must override 'connection'" }
end
module ClassMethods
def expects_valid_connection
it "should be a valid connection" do
connection.should be_valid
end
end
end
end
end
describe Connection do
include SpecHelpers::Connection
let(:connection) { Connection.new }
expects_valid_connection
end
Определение этих общих примеров более подробное, чем использование общих примеров. Думаю, я нахожу "it_behave_like" более неудобным, чем прямое распространение Rspec.
Очевидно, вы можете добавить аргументы в .expects_valid_connections
Я написал это, чтобы помочь другу rspec class: http://ruby-lambda.blogspot.com/2011/02/agile-rspec-with-let.html...
Ответ 3
Redacted - полностью окунулся в мое первое решение. Хо-Шэн Сяо дал большое объяснение, почему.
Вы можете предоставить it_behaves_like
блок следующим образом:
describe Connection do
it_behaves_like "any connection" do
let(:connection) { described_class.new(connection_settings) }
end
end
Ответ 4
Я обнаружил, что если вы явно не передаете параметр, объявленный let
, он будет доступен в общем примере.
Итак:
describe Connection do
let(:connection) { described_class.new(connection_settings) }
it_behaves_like "any connection"
end
соединение будет доступно в общих примерах
Ответ 5
Это работает для меня:
describe "numbers" do
shared_examples "a number" do |a_number|
let(:another_number) {
10
}
it "can be added to" do
(a_number + another_number).should be > a_number
end
it "can be subtracted from" do
(a_number - another_number).should be < a_number
end
end
describe "77" do
it_should_behave_like "a number", 77
end
describe "2" do
it_should_behave_like "a number", 2
end
end