【Rails】RakeタスクをMinitestでテストしてみた

はじめに

TDDでRakeタスクを作ろうとしたものの, テストをどう書けば良いのかがわかりませんでした. ネット上にあるのは, RSpecの記事や英語の記事ばかりだったため, MinitestでRakeタスクをテストする方法を書き残しておくことにしました.

主に参考にしたのは以下の記事です.

https://ieftimov.com/test-rake-tasks

Rakeタスクの例

具体例を考えるのが面倒なので, 自分が実際につくったタスクをもとに説明していきます.

以下は, YAMLファイルからデータを読み込んでusersテーブルに登録するタスクです.

# lib/tasks/user.rake
require 'yaml'

namespace :user do
  desc "insert users"
  task create_users: :environment do
    users = YAML.load_file(File.dirname(__FILE__) + "/users.yml")
    users.map do |user|
      User.create!(user)
    end
  end
end

テスト

テストコードは以下のように書きました.

# test/lib/create_users_test.rb
require 'test_helper'
require 'yaml'

class CreateUsersTest < ActionDispatch::IntegrationTest
  def setup
    # タスクをロード
    # Myappはアプリケーション名
    Myapp::Application.load_tasks

    # 挿入されるレコードの数を取得
    @count = YAML.load_file(Rails.root.to_s + '/lib/tasks/users.yml').count
  end

  test "users creation" do
    # タスク実行前後でユーザーの数が変化していることをテスト
    assert_difference 'User.count', @count do
      Rake::Task['user:create_users'].invoke
    end
  end
end

ポイントは, タスクをロードするコードと, タスクを実行するコードですね. これさえ押さえておけば, あとは普通のテストと一緒です.

ちなみにテストコード内のMyappはアプリケーション名ですが, これはconfig/application.rbに定義されているモジュールの名前です. アプリケーションごと異なるので注意してください.

また, test/libというディレクトリは自分で作りました.

テストの実行

ここで作成したテストは, rails test:libのように実行できないようです. rails testでは実行されました. 個別にテストしたい場合はファイル名を指定するのが良さそうですね.