概要
Sinatra::Base を継承して独自のコントローラクラスを作成している場合に rspec を使ってテストする方法を紹介します
少し工夫が必要でした
環境
- CentOS 7.3.1611
- ruby 2.3.3p222
- rspec 3.6.0
- sinatra 1.4.8
インストール
- bundle init
- vim Gemfile
gem "sinatra"
gem "rspec"
gem "rack-test"
- bundle install
独自のコントローラクラスの作成
- vim app.rb
require 'sinatra/base'
class MyApp < Sinatra::Base
get '/' do
'myapp'
end
end
このクラス内でアプリを起動 (run) することはしません
rackup で起動させる
- vim config.ru
require 'bundler'
Bundler.require
require './app'
run MyApp
これで rackup コマンドで MyApp アプリケーションが起動します
こうすることで独自のコントローラクラスを切り離しテストし易いようにします
もし MyApp 内で run! をしてしまうと rspec でテストを実行したときにアプリケーションが起動してしまいテストが進まなくなってしまいます
今回は直接アプリを起動しませんがもし起動させたい場合は
- bundle exec rackup
で 127.0.0.1:9292 で起動します
テストの作成
rspec --init
- vim spec/app_spec.rb
# -*- coding: utf-8 -*-
ENV['RACK_ENV'] = 'test'
require './app.rb'
require 'rspec'
require 'rack/test'
describe "MyApp のテスト" do
include Rack::Test::Methods
def app
MyApp
end
it "root にアクセスしたときに myapp を返却する" do
get '/'
expect(last_response.status).to eq 200
expect(last_response.body).to eq 'myapp'
end
end
- bundle exec rspec -f d spec/
MyApp のテスト
root にアクセスしたときに myapp を返却する
Finished in 0.02609 seconds (files took 0.18599 seconds to load)
1 example, 0 failures
こんな感じになれば成功です
おまけ spec_helper.rb を使って記述を楽にする
今のままだと describe するたびに include して def しなければなりません
そんなときに spec_helper.rb を使って設定しておくと省略することができます
- vim spec/spec_helper.rb
ENV['RACK_ENV'] = 'test'
require File.expand_path '../../app.rb', __FILE__
require 'rack/test'
require 'rspec'
module RSpecMixin
include Rack::Test::Methods
def app
MyApp
end
end
RSpec.configure do |config|
config.include RSpecMixin
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
config.shared_context_metadata_behavior = :apply_to_host_groups
end
デフォルトのコメントはすべて削除しました
要するにテスト内でやっていた処理を module 化して、それを Rspec.configure にあらかじめ設定してあげる感じです
テスト側は以下のように変更します
- vim spec/app_spec.rb
# -*- coding: utf-8 -*-
require File.expand_path '../spec_helper.rb', __FILE__
describe "MyApp のテスト" do
it "root にアクセスしたときに myapp を返却する" do
get '/'
expect(last_response.status).to eq 200
expect(last_response.body).to eq 'myapp'
end
end
かなりすっきりしました
冒頭で spec_helper.rb を require するだけになります
あとは同じようにテストを実行すれば OK です
- bundle exec rspec -f d spec/
最後に
Sinatra で独自のコントローラクラスを定義している場合に rspec でテストする方法を紹介しました
ポイントはアプリケーションの起動を rackup を使うということでした
0 件のコメント:
コメントを投稿