Ruby on Rails用のGemを実装し、そのテストを書く際、Railsのダミーアプリを対象として記述することになると思います。 rails pluginコマンドでもダミーアプリは生成できますが、より気軽にテストを書けるよう、この記事では最小構成のダミーアプリのつくり方を示します。

前提条件

この記事では、以下のような条件を満たすようなダミーアプリについて書いていきます。

  • Model/View/Controllerのテストを書ける構成にする
  • 動作に必要な最低限の実装を行なう
  • RSpecでテストを書く

動作環境

この記事の内容は、以下の各バージョンで動作を確認しています。

  • Ruby on Rails v4.2.6
  • RSpec v3.4.4

ディレクトリ構成

以下に、ダミーアプリと、これに対するModel/View/Controllerの各テスト例を含めたディレクトリ構成を示します。

dummyディレクトリが、ダミーアプリ本体となります。

spec
├── controllers
│   └── users_controller_spec.rb
├── dummy
│   ├── app
│   │   └── views
│   │       └── users
│   │           └── index.html.erb
│   └── application.rb
├── models
│   └── user_spec.rb
├── spec_helper.rb
└── views
    └── users
        └── index.html.erb_spec.rb

テスト

ダミーアプリを示す前に、まずダミーアプリにパスさせるModel/View/Controllerの各テストを示します。

以下をパスするようなダミーアプリを書いていくことになります。

Modelのテスト

spec/models/user_spec.rb:

require 'spec_helper'

describe User, type: :model do
  it 'has one' do
    User.create
    expect(User.count).to eq 1
  end
end

Viewのテスト

spec/views/users/index.html.erb_spec.rb:

require 'spec_helper'

describe 'users/index', type: :view do
  it 'displays content' do
    render
    expect(rendered).to match /users#index/
  end
end

Controllerのテスト

spec/controllers/users_controller_spec.rb:

require 'spec_helper'

describe UsersController, type: :controller do
  describe 'GET index' do
    it 'renders the index template' do
      get :index
      expect(response).to render_template(:index)
    end
  end
end

spec_helper.rb

参考までに、この記事で利用しているspec_helper.rbを以下に示します。

spec/spec_helper.rb:

require 'dummy/application'
require 'rspec/rails'

ダミーアプリ

それでは、ダミーアプリ本体のコード例を以下に示します。

application.rb

以下は、Model/View/Controllerすべてのテストを書くための実装例になっています。

開発するGemの性質によっては、Model/View/Controllerのうちテストに必要ないものもあると思います。 たとえばModelを使わない場合、ActiveRecordに関する実装は削除しても大丈夫です。

spec/dummy/application.rb:

require 'action_controller/railtie'
require 'active_record'

module Dummy
  class Application < Rails::Application
    config.secret_token = 'abcdefghijklmnopqrstuvwxyz0123456789'
    config.eager_load = false
  end
end

Dummy::Application.initialize!

ActiveRecord::Base.establish_connection(
  adapter: 'sqlite3',
  database: ':memory:'
)

#
# Migrates
#

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.timestamps null: false
    end
  end
end

CreateUsers.new.change

#
# Routes
#

Dummy::Application.routes.draw do
  root 'users#index'
end

#
# Models
#

class User < ActiveRecord::Base; end

#
# Controllers
#

class ApplicationController < ActionController::Base; end

class UsersController < ApplicationController
  def index; end
end

View

参考までに、テストをパスするためのViewを以下に示します。

spec/.../views/users/index.html.erb:

users#index

テストを実行する

以上で、前述したテストをパスできるようになります。 rspecコマンドで動作を確認してみます。

$ rspec
-- create_table(:users)
   -> 0.0027s
...

Finished in 0.04026 seconds (files took 1.09 seconds to load)
3 examples, 0 failures

serverとconsoleを実行する

ダミーアプリを対象にテストを実装する際、rails srails cでデバッグしたい場合もあると思います。

この場合、上記に加えてrailsコマンドとconfig.ruを作成します。

spec
└── dummy
    ├── bin
    │   └── rails
    └── config.ru

railsコマンド

まず、railsコマンドを実装します。 これはrails newで生成されるものとほとんど同じようになります。

spec/dummy/bin/rails:

#!/usr/bin/env ruby

APP_PATH = File.expand_path('../../application', __FILE__)

require 'rails/commands'

実行権限を付与する

作成したrailsコマンドに実行権限を付与します。

$ chmod +x spec/dummy/bin/rails

config.ru

rails sコマンドを実行すると、最終的にconfig.ruが実行されます。 そのため、このファイルを別途作成します。

spec/dummy/config.ru:

run Rails.application

以上でbin/rails sbin/rails cが実行できるようになります。

あわせて読みたい

おわりに

1つのファイルでモデルやコントローラを書けるため、テストを気軽に実装できるようになると思います。 Rails用のGemを開発する際の参考にしてみてください。