为什么我的guard-rspec测试失败了?

时间:2016-06-05 08:58:17

标签: ruby rspec guard

我使用this tutorial中描述的技术设置了guard-rspec环境。我也正在练习命名空间,如第{240页的Programing Ruby中所述。我当前的项目目录位于stack-overflow-post分支的github。 我正在使用:

❯ 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)>

但我不明白为什么因为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)>

在我看来,thread.rb中需要runner.rb的内容与我的测试无关。

  1. 为什么spec/thread_spec.rb中的原始测试失败?
  2. 为什么在lib/runner.rb中取消注释第2行会导致测试通过?
  3. 感谢您的帮助:)

    修改

    接受的答案帮助我解决了问题,在another post

    中可以找到更多问题

    编辑2: 还发了一个大发现:我一直在使用名为thread.rb的文件,有一个名为Thread的ruby类,所以当我在{{1}中说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) - &gt; thread.rb我可以rbb_thread.rb然后我会变成绿色:)

    编辑3: require 'rbb_thread'错误的另一个解决方案是thread.rb,因此不需要重命名

1 个答案:

答案 0 :(得分:1)

这里有一些事情:

  1. 当您运行规范时,您正在运行RSpec,就像应用程序一样,它的“config”在spec / spec_helper.rb中。我认为它是空的/不相关的。

  2. 如果您运行的是更新版本的RSpec,则只需将--require spec_helper放入.rspec文件即可,文件中不需要require "spec_helper"

  3. 最好在文件中第一次使用RSpec.describe而不是普通describe

  4. 您可以使用subject块以及described_class来提高可读性。它还允许您使用it { is.expected_to语法

  5. describe可以使用类名而不是字符串。这样就可以明显地了解您是否需要该文件。如果您传递了一个类,那么subject就会隐含。

  6. 由于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部分。