bundle gemするときには自動で lib/ 配下をrequireできるようにgemspecが作られるんだけど、GemじゃなくてRSpecを単体実行したいときに、どうやってパス追加すりゃええの?となったので自分用にメモ
前提
ディレクトリ構成
lib/
play.rb <-- class Playを定義したファイル
spec/
spec_helper.rb
play_spec.rb <-- Playを単体試験したいspec
RSpec導入
Gemfileに
gem 'rspec'
して、
bundle install
bundle exec rspec --init
したら、spec/spec_helper.rbが作られる。
単体試験の追加
lib/play.rb
class Play
def self.play
true
end
end
spec/play_spec.rb
require 'spec_helper'
RSpec.describe 'Play' do
it {
expect(Play.play).to eq(true)
}
end
RSpecが実行できるようにするために
なにもしないと
$ bundle exec rspec
F
Failures:
1) Play
Failure/Error: expect(Play.play).to eq(true)
NameError:
uninitialized constant Play
# ./spec/play_spec.rb:5:in `block (2 levels) in <top (required)>'
Playが無いと言われる。
解決策1:spec_helperの冒頭で、必要なファイルを追加
とてもダサいけどシンプルな方法。
spec/spec_helper.rb
require_relative '../lib/play'
# This file was generated by the `rspec --init` command. Conventionally, all
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
# The generated `.rspec` file contains `--require spec_helper` which will cause
# this file to always be loaded, without a need to explicitly require it in any
# files.
#
# Given that it is always loaded, you are encouraged to keep this file as
# light-weight as possible. Requiring heavyweight dependencies from this file
# will add to the boot time of your test suite on EVERY test run, even for an
# individual file that may not need all of that loaded. Instead, consider making
# a separate helper file that requires the additional dependencies and performs
# the additional setup, and require it from the spec files that actually need
# it.
#
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
RSpec.configure do |config|
# rspec-expectations config goes here. You can use an alternate
# assertion/expectation library such as wrong or the stdlib/minitest
# assertions if you prefer.
Playの場所を直指定してるので、通るに決まっている。
解決策2:bundlerのLOAD_PATHに追加する
解決策1は素直ではあるが、できればGem開発のときのように
- bundle execするときに
lib/
を読み込んで - 利用する側(RSpecのspec_helper)は
require "play"
で済ませたい
みたいなのをやりたいわけだ。
Gemfile に追記すると、実はこれができる。手段を問わないなら、これでいい。
gem 'rspec'
path = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
spec/spec_helper.rb
require 'play'
# This file was generated by the `rspec --init` command. Conventionally, all
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
# The generated `.rspec` file contains `--require spec_helper` which will cause
# this file to always be loaded, without a need to explicitly require it in any
# files.
#
# Given that it is always loaded, you are encouraged to keep this file as
# light-weight as possible. Requiring heavyweight dependencies from this file
# will add to the boot time of your test suite on EVERY test run, even for an
# individual file that may not need all of that loaded. Instead, consider making
# a separate helper file that requires the additional dependencies and performs
# the additional setup, and require it from the spec files that actually need
# it.
#
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
RSpec.configure do |config|
# rspec-expectations config goes here. You can use an alternate
# assertion/expectation library such as wrong or the stdlib/minitest
# assertions if you prefer.