为什么我的 guard-rspec 测试失败了?
Why is my guard-rspec test failing?
我使用 stack-overflow-post
分支中 this tutorial. I'm also practicing namespacing as described in Programing Ruby starting on page 240. My current project directory is on github 中描述的技术设置了我的 guard-rspec
环境。
我正在使用:
❯ ruby -v
ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-darwin15.0]
❯ rbenv -v
rbenv 1.0.0
❯ rbenv versions
system
* 2.1.1 (set by /Users/max/Google Drive/devbootcamp/phase-0-ruby-bulletin-board/.ruby-version)
2.1.5
2.2.3
2.3.1
❯ bundle exec guard -v
Guard version 2.3.0
我 运行 在 spec/thread_spec.rb
参加考试:
require 'spec_helper'
describe 'RubyBulletinBoard::Thread' do
let (:thread) { RubyBulletinBoard::Thread.new }
it { expect(thread).to be_kind_of(RubyBulletinBoard::Thread) }
# it 'has a valid uuid' do
# p thread.uuid
# expect(thread.uuid).to be_kind_of(String)
# end
# it 'has editable title' do
# default_title = thread.title
# thread.title = "#{default_title} something different"
# new_title = thread.title
# expect(default_title == new_title).to eq(false)
# end
end
但是失败了:
01:50:07 - INFO - Running: ./spec/thread_spec.rb:5
Run options: include {:locations=>{"./spec/thread_spec.rb"=>[5]}}
RubyBulletinBoard::Thread
example at ./spec/thread_spec.rb:5 (FAILED - 1)
Failures:
1) RubyBulletinBoard::Thread
Failure/Error: let (:thread) { RubyBulletinBoard::Thread.new }
NameError:
uninitialized constant RubyBulletinBoard::Thread
# ./spec/thread_spec.rb:4:in `block (2 levels) in <top (required)>'
# ./spec/thread_spec.rb:5:in `block (2 levels) in <top (required)>'
Finished in 0.00055 seconds
1 example, 1 failure
Failed examples:
rspec ./spec/thread_spec.rb:5 # RubyBulletinBoard::Thread
[1] guard(main)>
但我不知道为什么,因为 class RubyBulletinBoard::Thread
确实存在于 lib/ruby_bulletin_board/thread.rb
:
require_relative 'id'
module RubyBulletinBoard
class Thread
attr_reader :uuid
attr_accessor :title
def initialize
@uuid = IdCreator.create_id
@title = title
end
end
end
更奇怪的是,当我在 lib/ruby_bulletin_board/runner.rb
中取消注释第 2 行时,测试通过了:
require_relative 'example'
# require_relative 'thread' # <--- THIS IS LINE 2
module RubyBulletinBoard
class Runner
attr_accessor :greeter, :thread
def initialize
@greeter = RSpecGreeter.new
# @thread = RubyBulletinBoard::Thread.new
end
def run
greeter.greet
# p @thread.class
end
end
end
rspec 输出:
01:53:57 - INFO - Running: ./spec/thread_spec.rb:5
Run options: include {:locations=>{"./spec/thread_spec.rb"=>[5]}}
RubyBulletinBoard::Thread
should be a kind of RubyBulletinBoard::Thread
Finished in 0.00114 seconds
1 example, 0 failures
[1] guard(main)>
在我看来,在 runner.rb
中包含要求 thread.rb
与我的测试无关。
- 为什么我在
spec/thread_spec.rb
中的原始测试失败了?
- 为什么取消注释
lib/runner.rb
中的第 2 行会导致测试通过?
感谢您的帮助:)
编辑:
接受的答案帮助我解决了问题 运行,更多问题可以在
中找到
编辑 2:
也刚刚有了一个大发现:我一直在使用一个名为 thread.rb
的文件,有一个名为 ruby class 的线程,所以当我一直在说 require 'thread'
我的 thread_spec.rb
它一直给我错误:
[1] guard(main)>
17:57:09 - INFO - Running: spec/thread_spec.rb
/Users/max/Google Drive/devbootcamp/phase-0-ruby-bulletin-board/spec/thread_spec.rb:4:in `<top (required)>': uninitialized constant RubyBulletinBoard (NameError)
from /Users/max/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/configuration.rb:1361:in `load'
from /Users/max/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/configuration.rb:1361:in `block in load_spec_files'
from /Users/max/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/configuration.rb:1359:in `each'
from /Users/max/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/configuration.rb:1359:in `load_spec_files'
from /Users/max/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:106:in `setup'
from /Users/max/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:92:in `run'
from /Users/max/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:78:in `run'
from /Users/max/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:45:in `invoke'
from /Users/max/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/exe/rspec:4:in `<top (required)>'
from bin/rspec:17:in `load'
from bin/rspec:17:in `<main>'
17:57:10 - ERROR - Failed: "bin/rspec -f progress -r /Users/max/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/guard-rspec-4.7.2/lib/guard/rspec_formatter.rb -f Guard::RSpecFormatter --failure-exit-code 2 spec/thread_spec.rb" (exit code: 1)
通过重命名 thread.rb
-> rbb_thread.rb
然后我可以 require 'rbb_thread'
并且我将从红色变为绿色 :)
编辑 3:
thread.rb
错误的另一种解决方案是 require_relative ../lib/thread
,因此不需要重命名
这里有几件事:
当你运行宁规范时,你运行宁RSpec就像一个应用程序,它"config"在spec/spec_helper.rb。我假设它是 empty/irrelevant.
如果您运行正在使用 RSpec 的更新版本,您只需将 --require spec_helper
放入 .rspec
文件中即可您的文件中不需要 require "spec_helper"
。
最好在文件中第一次使用 RSpec.describe
而不是普通的 describe
。
您可以使用 subject
块来提高可读性以及 described_class
。它还允许您使用 it { is.expected_to
语法
describe
可以使用 class 名称而不是字符串。这样一来,您是否需要该文件就很明显了。如果传递 class,则 subject
变为隐式。
由于 RSpec 就像一个单独的应用程序,默认情况下它不包含您自己的库文件(RSpec 的较新版本确实将 lib
添加到 LOAD_PATH
).所以你的测试必须单独要求他们测试的任何文件,例如
require 'spec_helper'
describe 'RubyBulletinBoard::Thread' do
let (:thread) { RubyBulletinBoard::Thread.new }
it { expect(thread).to be_kind_of(RubyBulletinBoard::Thread) }
变成:
require 'ruby_bulletin_board/thread'
RSpec.describe RubyBulletinBoard::Thread do
it { is_expected.to be_kind_of(RubyBulletinBoard::Thread) }
如果上面的require
失败了,这意味着你需要把lib
放在你的加载路径中。如果是这种情况,请检查您的 spec/spec_helper.rb
。
如果您的 spec/spec_helper.rb
是空的(或没有任何重要的东西),您可能需要将其与 .rspec
和 运行 rspec --init
一起删除以生成一个适合您的良好入门模板。请务必取消注释 =begin
和 =end
部分。
我使用 stack-overflow-post
分支中 this tutorial. I'm also practicing namespacing as described in Programing Ruby starting on page 240. My current project directory is on github 中描述的技术设置了我的 guard-rspec
环境。
我正在使用:
❯ ruby -v
ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-darwin15.0]
❯ rbenv -v
rbenv 1.0.0
❯ rbenv versions
system
* 2.1.1 (set by /Users/max/Google Drive/devbootcamp/phase-0-ruby-bulletin-board/.ruby-version)
2.1.5
2.2.3
2.3.1
❯ bundle exec guard -v
Guard version 2.3.0
我 运行 在 spec/thread_spec.rb
参加考试:
require 'spec_helper'
describe 'RubyBulletinBoard::Thread' do
let (:thread) { RubyBulletinBoard::Thread.new }
it { expect(thread).to be_kind_of(RubyBulletinBoard::Thread) }
# it 'has a valid uuid' do
# p thread.uuid
# expect(thread.uuid).to be_kind_of(String)
# end
# it 'has editable title' do
# default_title = thread.title
# thread.title = "#{default_title} something different"
# new_title = thread.title
# expect(default_title == new_title).to eq(false)
# end
end
但是失败了:
01:50:07 - INFO - Running: ./spec/thread_spec.rb:5
Run options: include {:locations=>{"./spec/thread_spec.rb"=>[5]}}
RubyBulletinBoard::Thread
example at ./spec/thread_spec.rb:5 (FAILED - 1)
Failures:
1) RubyBulletinBoard::Thread
Failure/Error: let (:thread) { RubyBulletinBoard::Thread.new }
NameError:
uninitialized constant RubyBulletinBoard::Thread
# ./spec/thread_spec.rb:4:in `block (2 levels) in <top (required)>'
# ./spec/thread_spec.rb:5:in `block (2 levels) in <top (required)>'
Finished in 0.00055 seconds
1 example, 1 failure
Failed examples:
rspec ./spec/thread_spec.rb:5 # RubyBulletinBoard::Thread
[1] guard(main)>
但我不知道为什么,因为 class RubyBulletinBoard::Thread
确实存在于 lib/ruby_bulletin_board/thread.rb
:
require_relative 'id'
module RubyBulletinBoard
class Thread
attr_reader :uuid
attr_accessor :title
def initialize
@uuid = IdCreator.create_id
@title = title
end
end
end
更奇怪的是,当我在 lib/ruby_bulletin_board/runner.rb
中取消注释第 2 行时,测试通过了:
require_relative 'example'
# require_relative 'thread' # <--- THIS IS LINE 2
module RubyBulletinBoard
class Runner
attr_accessor :greeter, :thread
def initialize
@greeter = RSpecGreeter.new
# @thread = RubyBulletinBoard::Thread.new
end
def run
greeter.greet
# p @thread.class
end
end
end
rspec 输出:
01:53:57 - INFO - Running: ./spec/thread_spec.rb:5
Run options: include {:locations=>{"./spec/thread_spec.rb"=>[5]}}
RubyBulletinBoard::Thread
should be a kind of RubyBulletinBoard::Thread
Finished in 0.00114 seconds
1 example, 0 failures
[1] guard(main)>
在我看来,在 runner.rb
中包含要求 thread.rb
与我的测试无关。
- 为什么我在
spec/thread_spec.rb
中的原始测试失败了? - 为什么取消注释
lib/runner.rb
中的第 2 行会导致测试通过?
感谢您的帮助:)
编辑:
接受的答案帮助我解决了问题 运行,更多问题可以在
编辑 2:
也刚刚有了一个大发现:我一直在使用一个名为 thread.rb
的文件,有一个名为 ruby class 的线程,所以当我一直在说 require 'thread'
我的 thread_spec.rb
它一直给我错误:
[1] guard(main)>
17:57:09 - INFO - Running: spec/thread_spec.rb
/Users/max/Google Drive/devbootcamp/phase-0-ruby-bulletin-board/spec/thread_spec.rb:4:in `<top (required)>': uninitialized constant RubyBulletinBoard (NameError)
from /Users/max/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/configuration.rb:1361:in `load'
from /Users/max/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/configuration.rb:1361:in `block in load_spec_files'
from /Users/max/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/configuration.rb:1359:in `each'
from /Users/max/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/configuration.rb:1359:in `load_spec_files'
from /Users/max/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:106:in `setup'
from /Users/max/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:92:in `run'
from /Users/max/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:78:in `run'
from /Users/max/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:45:in `invoke'
from /Users/max/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/exe/rspec:4:in `<top (required)>'
from bin/rspec:17:in `load'
from bin/rspec:17:in `<main>'
17:57:10 - ERROR - Failed: "bin/rspec -f progress -r /Users/max/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/guard-rspec-4.7.2/lib/guard/rspec_formatter.rb -f Guard::RSpecFormatter --failure-exit-code 2 spec/thread_spec.rb" (exit code: 1)
通过重命名 thread.rb
-> rbb_thread.rb
然后我可以 require 'rbb_thread'
并且我将从红色变为绿色 :)
编辑 3:
thread.rb
错误的另一种解决方案是 require_relative ../lib/thread
,因此不需要重命名
这里有几件事:
当你运行宁规范时,你运行宁RSpec就像一个应用程序,它"config"在spec/spec_helper.rb。我假设它是 empty/irrelevant.
如果您运行正在使用 RSpec 的更新版本,您只需将
--require spec_helper
放入.rspec
文件中即可您的文件中不需要require "spec_helper"
。最好在文件中第一次使用
RSpec.describe
而不是普通的describe
。您可以使用
subject
块来提高可读性以及described_class
。它还允许您使用it { is.expected_to
语法describe
可以使用 class 名称而不是字符串。这样一来,您是否需要该文件就很明显了。如果传递 class,则subject
变为隐式。
由于 RSpec 就像一个单独的应用程序,默认情况下它不包含您自己的库文件(RSpec 的较新版本确实将 lib
添加到 LOAD_PATH
).所以你的测试必须单独要求他们测试的任何文件,例如
require 'spec_helper'
describe 'RubyBulletinBoard::Thread' do
let (:thread) { RubyBulletinBoard::Thread.new }
it { expect(thread).to be_kind_of(RubyBulletinBoard::Thread) }
变成:
require 'ruby_bulletin_board/thread'
RSpec.describe RubyBulletinBoard::Thread do
it { is_expected.to be_kind_of(RubyBulletinBoard::Thread) }
如果上面的require
失败了,这意味着你需要把lib
放在你的加载路径中。如果是这种情况,请检查您的 spec/spec_helper.rb
。
如果您的 spec/spec_helper.rb
是空的(或没有任何重要的东西),您可能需要将其与 .rspec
和 运行 rspec --init
一起删除以生成一个适合您的良好入门模板。请务必取消注释 =begin
和 =end
部分。