问题
I set up my guard-rspec
environment using the techniques described in this tutorial. I'm also practicing namespacing as described in Programing Ruby starting on page 240. My current project directory is on github in the stack-overflow-post
branch.
I'm using:
❯ 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
I'm running a test in 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
However it's failing:
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)>
But I have no idea why because the class RubyBulletinBoard::Thread
does exist in 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
Even weirder, when I uncomment line 2 in lib/ruby_bulletin_board/runner.rb
the test passes:
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 output:
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)>
It seems to me that including requiring thread.rb
in runner.rb
would have nothing to do with my tests.
- Why is my original test in
spec/thread_spec.rb
failing? - Why does uncommenting line 2 in
lib/runner.rb
cause the test to pass?
Thanks for your help :)
Edit:
The accepted answer helped me get things up and running, more questions can be found in another post
Edit 2:
Also just made a big discovery: I've been using a file named thread.rb
, there is a ruby class named Thread, so when I've been saying require 'thread'
in my thread_spec.rb
it's been giving me errors:
[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)
by renaming thread.rb
-> rbb_thread.rb
I can then require 'rbb_thread'
and I'm going red to green :)
Edit 3:
Another solution for the errors with thread.rb
is to require_relative ../lib/thread
and so no rename is required
回答1:
A few things here:
When you're running specs, you're running RSpec like an application and it's "config" is in spec/spec_helper.rb. I'll assume it's empty/irrelevant.
If you're running a more recent version of RSpec, you can just place
--require spec_helper
in your.rspec
file and you won't need therequire "spec_helper"
in your files.It's best to use
RSpec.describe
instead of plaindescribe
the first time in a file.You can use a
subject
block for more readability along withdescribed_class
. It also lets you useit { is.expected_to
syntaxdescribe
can take a class name instead of a string. This way it makes it obvious if you've required the file or not. If you pass a class, thensubject
becomes implicit.
Since RSpec is like a separate app, it doesn't include your own library files by default (newer versions of RSpec do add lib
to LOAD_PATH
). So your tests have to individually require any files they test, e.g.
require 'spec_helper'
describe 'RubyBulletinBoard::Thread' do
let (:thread) { RubyBulletinBoard::Thread.new }
it { expect(thread).to be_kind_of(RubyBulletinBoard::Thread) }
becomes:
require 'ruby_bulletin_board/thread'
RSpec.describe RubyBulletinBoard::Thread do
it { is_expected.to be_kind_of(RubyBulletinBoard::Thread) }
If the above require
fails, it means you need to put lib
in your load path. Check your spec/spec_helper.rb
if that's the case.
If your spec/spec_helper.rb
is empty (or doesn't have anything important), you may want remove it along with .rspec
and run rspec --init
to generate a good started template for you. Be sure you uncomment the =begin
and =end
sections there.
来源:https://stackoverflow.com/questions/37640135/why-is-my-guard-rspec-test-failing