我目前正在参加Coursera的免费 Ruby on Rails简介课程。我正在进行第三项任务,其中包含创建People
类,其中您具有搜索功能等功能。
当我使用他们设计的单元测试运行rspec
时,我遇到了一个奇怪的错误。我99%肯定错误在于单元测试。具体来说,在我触摸任何文件之前 ,我收到以下错误:
raise <<-EOS
#{description} accessed in #{article} #{hook_expression} hook at:
#{CallerFilter.first_non_rspec_line}
`let` and `subject` declarations are not intended to be called
in #{article} #{hook_expression} hook, as they exist to define state that
is reset between each example, while #{hook_expression} exists to
#{hook_intention}.
EOS
RuntimeError:
let declaration `class` accessed in an `after(:context)` hook at:
/Users/<username>/.rvm/gems/ruby-2.4.0/gems/rspec-core-3.7.1/exe/rspec:4:in `<top (required)>'
`let` and `subject` declarations are not intended to be called
in an `after(:context)` hook, as they exist to define state that
is reset between each example, while `after(:context)` exists to
cleanup state that is shared across examples in an example group.
对于初学者,我并不完全理解他们用来描述他们的测试的语法。其次,这是Coursera类的作者写的原始测试文件:
require 'rspec'
require 'rspec/its'
require_relative '../module2_lesson3_formative.rb'
describe "lesson3" do
context "check results" do
p1 = Person.new("Ivana", "Trump")
p2 = Person.new("Eric", "Trump")
p3 = Person.new("Melania", "Trump")
p4 = Person.new("Marla", "Maples")
it "unexpected search result" do
expect(Person.search("Trump").size).to be == 3
end
end
context "check instance properties" do
subject(:john) { Person.new("Chris", "Christie") }
it "missing first_name" do
is_expected.to respond_to(:first_name)
end
it "missing last_name" do
is_expected.to respond_to(:last_name)
end
end
context "check class properties" do
subject(:class) { Person }
it "missing search" do
is_expected.to respond_to(:search)
end
end
end
我希望当我运行rspec
时,有人可以向我解释调试信息。我正在使用RSpec 3.7
,我猜是问题,因为它表明它可能是版本升级的东西here。这也可以解释这个类的作者没有故意推翻坏代码的事实。对我来说解决这个问题的最佳方法是什么?为什么这样的行是这样的:
subject(:john) { Person.new("Chris", "Christie") }
状况不好?非常感谢!真的很感激你的时间:)
答案 0 :(得分:1)
这似乎解决了rspec
抱怨的问题:
describe "lesson3" do
subject { person } # ADDED THIS LINE
context "check results" do
p1 = Person.new("Ivana", "Trump")
p2 = Person.new("Eric", "Trump")
p3 = Person.new("Melania", "Trump")
p4 = Person.new("Marla", "Maples")
it "unexpected search result" do
expect(Person.search("Trump").size).to be == 3
end
end
context "check instance properties" do
let(:person) { Person.new("Chris", "Christie") } # CHANGED THIS LINE
it "missing first_name" do
is_expected.to respond_to(:first_name)
end
it "missing last_name" do
is_expected.to respond_to(:last_name)
end
end
context "check class properties" do
let(:person) { Person } # CHANGED THIS LINE
it "missing search" do
is_expected.to respond_to(:search)
end
end
end
我仍然不确定为什么,或者差异是什么意思。我希望有人能够更深入地解释它。
答案 1 :(得分:1)
为了更改规范的主题类别,您可以根据每个示例“重新定义”主题,或者根据需要进行重新定义。
当尝试使用let或subject更改规范主题的类时,您会收到详细的错误(警告)消息:
let
和subject
声明不打算在。中调用after(:context)
挂钩,因为它们存在以定义重置的状态 每个例子之间
因此,您无法明确设置主题的类,因为它将在每个运行示例中重置。
您可以使用subject
将主题设置为“检查类属性”上下文中的Person对象,这样is_expected
将检查响应类方法搜索的此对象,像:
context "check class properties" do
subject { Person }
it 'missing search' do
is_expected.to respond_to(:search)
end
end