RailsのオリジナルRakeタスクのテスト rspec 3.0.x編

モリジュン(@zyunnosuke)氏が、RailsでオリジナルRakeタスク作成からRSpecテストまでの記事において、Rakeタスクの作り方、RSpecによるテストの仕方を解説してます。その記事では、RSpecは2.x系で、テストコードで、shouldを使っています。今回、RSpec 3.0.xで、expectを使いたいので、挑戦してみました。

1. プロジェクトの作成

$ rails new rake-test-sample
$ cd rake-test-sample
$ bundle update
$ bundle install

2. モデルの作成

rakeのタスクの内容をクラスに抽出したものとして、モデル ReportGeneratorを作成する。

$ rails generate model report_generator
$ bundle exec db:migrate

モデルクラス ReportGeneratorには、次の内容を記述。

class ReportGenerator < ActiveRecord::Base
  def self.generate
    puts "ReportGenerator.generate called."
  end
end
&#91;/ruby&#93;

クラスメソッドで、ダミーな処理を記述している。

3. Rakeタスクファイルの作成

&#91;bash&#93;
$ rails generate task reports
&#91;/bash&#93;

生成されたlib/tasks/repots.rakeに次の内容を記述。元記事のまんまです。

&#91;ruby&#93;
namespace :reports do
  # descの記述は必須
  desc "Generate report"

  # :environmentはモデルにアクセスするのに必須
  task :generate => :environment do
    # 処理を記述
    ReportGenerator.generate
  end
end

タスクの確認は

$ rake -vT |grep reports
rake reports:generate                   # Generate report

タスクの実行は

$ rake reports:generate

4. Gemfileにrspecとrspec-its の追加

元記事では、specファイルで、itsを使っていますが、itsはrspec 3.0.xではサポートされなくなりました。RSpec の入門とその一歩先へ、第3イテレーション ~RSpec 3バージョン~によると、gem rspec-itsを導入すると、itsが使えるとのことです。そこで、元記事に書かれていたrake_shared_context のgemと共に、Gemfileに以下を追加。

group :development, :test do
  gem 'rake_shared_context'
  gem 'rspec-rails', '3.0.0'
  gem 'rspec-its', '1.0.1'
end
$ bundle update
$ bundle install

を実行。

5. RakeタスクのRSpecの作成

rspecによるテストが出来るように次のコマンドを実行します。

$ bundle exec rails generate rspec:install

元記事では、spec/lib/tasks/reports_rake_spec.rbファイルは、次の内容でした。

require 'spec_helper'

describe 'reports:generate' do
  include_context 'rake'

  its(:prerequisites) { should include('environment') }

  it 'generates the report' do
    ReportGenerator.should_receive(:generate)
    subject.invoke
  end
end

これは、rspec 2.x向けの記述なので、次のように書き換えます。

require 'spec_helper'

describe 'reports:generate' do
  include_context 'rake'

  its(:prerequisites) { is_expected.to include('environment') }

  it 'generate the report' do
    expect(ReportGenerator).to receive(:generate)
    subject.invoke
  end
end

記述の仕方は、RSpec の入門とその一歩先へ、第3イテレーション ~RSpec 3バージョン~ や、RSpec 3の重要な変更を参考にしました。

6. Rakeテストの実行

$ bundle exec rspec spec/lib/tasks/reports_rake_spec.rb

warningが多いので、プロジェクトディレクトリの .rspecファイルで、–warningsの行を削除しておきます。

`find_and_eval_shared’: Could not find shared context “rake” (ArgumentError)

というエラーが出ますが、spec/spec_helper.rbの冒頭に次の記述をします。

# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'

この記述は、パーフェクトRuby on Railsを参考にしました。

再度、テストを実行。

$ bundle exec rspec spec/lib/tasks/reports_rake_spec.rb
...
Finished in 0.01324 seconds (files took 1.22 seconds to load)
2 examples, 0 failures

テストが通りました。

7. ソースの公開場所

andropenguin/rake-test-sample

8. Special Thanks

RedmineでGmailにメール送信するための設定

RedmienでGmailにメール送信するための設定について、以前ハマったので、メモ。Remdineのバージョンは、2.5.1。

config/configuration.ymlで次のようにする。user_nameとpaaswordを適宜変更する。

production:

# specific configuration options for development environment
# that overrides the default ones
# —————————————————————————-
email_delivery:
delivery_method: :smtp
smtp_settings:
#tls: true
enable_starttls_auto: true
address: “smtp.gmail.com”
port: 587
domain: “smtp.gmail.com” # ‘your.domain.com’ for GoogleApps
authentication: :plain
user_name: “hoge@gmail.com”
password: “himitsu”
# ————————————————————————–
development:

WebブラウザでのRedmineの設定は、ググって。あと、メールがスパムメールボックスに入っていることがあるので、注意する。
(フォーマッタがうまく機能しないorz。ymlの書式に従って、行頭にスペースを入れる必要がある。)

八木俊広氏のAndroidオープンソースライブラリ徹底活用のサンプルのbuild.gradle集を作った

八木俊広氏のAndroidオープンソースライブラリ徹底活用のサンプルをIntelliJ IDEAでビルドしました。build.gradleファイル集を公開します。アプリのソースファイルは原則的に含めませんが、一部のアプリが動かないケースがあったので、その場合は、ソースファイルを改変したものも含めました。また、flickrサービスが、最近、SSL接続を要求するようになったのか、flickrサービスにアクセスするアプリが全く動きませんでした。それらのアプリでは、build.gradleを含めないことがあります。

StyledDialogsを使って、Customized List Dialog Fragementを作った

Androidライブラリ inmite/android-styled-dialogs を使って、リストを表示するDialog Fragmentを作ってみました。

特徴は、以下の通りです。

  • Android 3.1以前にも対応する、DialogFragmentベースのリスト表示するダイアログを実装した。
  • リストの項目を選択すると、どの項目が選択されたか検知できる。
  • ダイアログを表示中に画面回転をやった後、リストの項目やCancelをタップしても、アプリが落ちることはない。

ライブラリのソースファイルに添付のデモには、リストを表示するダイアログの例があるのですが、getTargetFragment()の返り値がnullになっていて、ダイアログのリストの項目をタップした時、どの項目がタップされたか拾えませんでした。本アプリではダイアログを開く画面を、Fragmentにして、そこで、setTagetFragmentでセットすることによって、この問題を解決しました。また、デモでは、Fragmentの実装にはよく見られるシングルトンパターンに関して、似たコーディングはあったのですが、あらわにはコーディングされていなかったので、ソースを書き換えました。

サンプルプログラムのソースファイルを GitHub andropenguin/CustomStyledDialogsSample
に置きます。

参考サイト