Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
3
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

RSpecで独自metadataを利用する

RSpec の独自 metadata が便利だったので、利用方法と思い付く使用ケースをまとめます。

環境

$ bundle exec rails -v
Rails 6.0.2.2

$ bundle exec rspec -v
RSpec 3.9
  - rspec-core 3.9.1
  - rspec-expectations 3.9.0
  - rspec-mocks 3.9.1
  - rspec-rails 3.9.0
  - rspec-support 3.9.2

metadata の宣言

it (example) ブロックに :hoge という metadata を宣言する場合は下記の様になります。

RSpec.describe 'Example' do
  it 'test1', :hoge do
  end
end

するとブロック内で宣言した metadata が利用できるようになります。

it 'Test 1', :hoge do |example|
  p example.metadata[:hoge] # true
end

値を指定することもできます。 ※ Symbol のままだと初期値は true

it 'Test 1', hoge: 'fuga' do |example|
  p example.metadata[:hoge] # fuga
end

使用ケース

独自 metadata を before や let ブロックで利用する

before や let の処理を skip する方法

# 特定条件下で skip したい前提処理 (before)
before do |example|
  next if example.metadata[:skip_before]

  # skip_before の値が正だと skip される処理
  @post = FactoryBot.create :post
end

# 特定条件下で skip したい前提処理 (let!)
let(:user) do |example|
  return if example.metadata[:skip_create_user]

  # skip_create_user の値が正だと skip される処理
  FactoryBot.create :user
end

it 'Test 1', :skip_before do
  expect(@post).to be_nil # before は skip されたので nil
  expect(user).to be_present
end

it 'Test 2', :skip_create_user do
  expect(@post).to be_present
  expect(user).to be_nil # let は skip されたので nil
end

作成するリソースを宣言する方法

# metadata を使って作成するレコード数を指定
let(:user_count) { |example| example.metadata[:user_count] || 1 }
let(:users) { FactoryBot.create_list :user, user_count }

it 'Test 1' do
  expect(users.count).to eq 1
end

it 'Test 2', user_count: 3 do |example|
  expect(users.count).to eq 3
  expect(users.count).to eq example.metadata[:user_count]
end
# metadata を使って作成するリソースのデータを指定する
let(:user_name) { |example| example.metadata[:user_name] || 'alice' }
let(:user) { FactoryBot.create :user, name: user_name }

it 'Test 1' do
  expect(user.name).to eq 'alice'
end

it 'Test 2', user_name: 'bob' do |example|
  expect(user.name).to eq 'bob'
  expect(user.name).to eq example.metadata[:user_name]
end

独自 metadata を指定して RSpec を実行する

RSpec.describe 'Example' do
  context 'xxxとして', :hoge do
    it 'Test 1' do
    end

    it 'Test 2' do
    end
  end

  context 'yyyとして' do
    it 'Test 3' do
    end
  end

  context 'zzzとして' do
    it 'Test 4', :hoge do
    end
  end
end

独自 metadata を指定して実行できる。 ※ context や describe で指定すると一括で指定可能

$ bundle exec rspec -t hoge
Run options: include {:hoge=>true}

Example
  hogeとして
    Test 1
    Test 2
  piyoとして
    Test 4

事前の設定などに metadata を使用する

サンプル用のユーザを先に作成したい場合

require 'rails_helper'

RSpec.describe 'Example' do
  it 'Test 1', :sample_users do # 独自 metadata を宣言
    expect(User.count).to eq 10
  end

  it 'Test 2' do
    expect(User.count).to eq 0
  end
end
spec/rails_helper.rb
RSpec.configure do |config|
  # ...

  config.before(:each, sample_users: true) do
    # sample_users metadata が true のブロックでは事前にユーザを作成する
    FactoryBot.create_list :user, 10
  end
end

参考

以上です。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
3
Help us understand the problem. What are the problem?