RSpecãšã®è·é¢ãçž®ããã·ã³ãã«ãªæžãæ¹
IVRyã§ãããã¯ãšã³ããšã³ãžãã¢ãããŠããå³¶çã§ãã
IVRyã§ã¯ãRailsãå©çšããŠäžéšã®ãµãŒãã¹ãæäŸããŠããããã¹ãã¯ãRSpecãå©çšããŠããŸãã
10幎è¿ãRailsã䜿ã£ãéçºã«æºãã£ãŠããŸãããRailsãå§ããŠæ°å¹Žã¯ãRSpecãæžãããšããšãŠãåå«ã§ããã
ãããä»ã§ã¯ãRSpecãªãã§ã¯ç¶ç¶çãªéçºã¯é£ãããšããæèã«ãŸã§ãªã£ãã®ã ãããèªåã§ãäžæè°ã«æããŸãã
èŠææèãå€ãã£ããã£ããã¯ãæ¢å颿°ãä¿®æ£ããéããã®é¢æ°ãå©çšããŠããã³ãŒããç Žå£ãããããªä¿®æ£ãRSpecã®ãããã§æ°ã¥ããããšã§ãã
ãããã£ãçµéšãäœéšãããšãRSpecãªãã®éçºã§ããªããªããŸãã
å®å¿ããŠæ¹åã»ãªãã¡ã¯ã¿ãªã³ã°ãè¡ããŸãã
ä»åã®èšäºã§ã¯ãäœããã£ããã§ãRSpecã®èŠææèãææã§ããããèšããŠããããšæããŸãã
- æåã«å®çŸ©ãããã¹ãã¯ãäžçªã·ã³ãã«ãªæ£åžžç³»ã確èªãã
- modelã®ãã¹ãããæžããŠãã
- describe, context, itãæžã
- rubocopãå ¥ããŠã1ã€ã®é¢æ°ã®ã³ãŒãéãã§ããéãæžãããã·ã³ãã«ã«ãã
- matcherã¯èŠããªããŠè¯ã
â» ãããã¯ã誰ããåãããã«æãããšããããã§ã¯ãªãã§ãããåœããåããšã°ãããããããŸããããç§ã«ãšã£ãŠãã£ããã«ãªã£ãäºæã§ãã
RSpecã«ã€ããŠæžããªããŠã仿ŽïŒãšãèšããªãã§ð
1. æåã«å®çŸ©ãããã¹ãã¯ãäžçªã·ã³ãã«ãªæ£åžžç³»ã確èªãã
äžçªã·ã³ãã«ãªãã¹ãã³ãŒãã¯äœããšããã°ãæ£åžžç³»ã®åŠçã§ãã
æ£åžžç³»ãå®çŸ©ããåŸãç°åžžç³»ã®ãã¹ãã³ãŒãã远å ããŠãããŸãã
æ©éãã³ãŒãã玹ä»ããŸãã
ããUserã¢ãã«ããããemailãšnameãå¿ é ãšããæã以äžã®ãããªã¯ã©ã¹ãå®çŸ©ããããšæããŸãã
class User < ApplicationRecord
validates :email, presence: true
validates :name, presence: true
end
ãã®ã¯ã©ã¹ã«å¯Ÿå¿ããæ£åžžç³»ã®ãã¹ãã³ãŒãã¯ã以äžã®ããã«ãªããŸãã
RSpec.describe User, type: :model do
describe '.valid' do
let(:user) { build(:user, email: 'ãã¹ã', name: 'test@example.com') } # FactoryBotãå©çšããŠããŸãã
it { expect(user.valid).to be_truthy }
end
end
äžèšã®ããã«æ£åžžç³»ã®ã³ãŒããå®çŸ©ãããŠããã°ãåŸã¯ç°åžžç³»ã®æ¡ä»¶ã远å ããŠããã ãã«ãªããŸãã
RSpec.describe User, type: :model do
describe '.valid' do
let(:user) { build(:user, email: 'test@example.com', name: 'ãã¹ã') } # FactoryBotãå©çšããŠããŸãã
it { expect(user.valid).to be_truthy }
context 'when email is empty' do
let(:user) { build(:user, email: '', name: 'ãã¹ã') }
it { expect(user.valid).to be_falsey }
end
context 'when name is empty' do
let(:user) { build(:user, email: 'test@example.com', name: '') }
it { expect(user.valid).to be_falsey }
end
end
end
ããã«æ°ã¥ããããšãããã¹ããæžãããŒãã«ãäžçªäžããŠãããŸããã
2. modelã®ãã¹ãããæžããŠãã
modelã®ãã¹ãããæžãããšã§ãé¢é£ãããã¹ããç¹ã«Requestã¹ããã¯ãæžãããŒãã«ãäžãããŸããã
åè¿°ã®ã¢ãã«ã®ãã¹ãã§æžãã let(:user) { build(:user, email: 'test@example.com', name: 'ãã¹ã') } ãå©çšããŠãusers_controllerã®Requestã¹ããã¯ãæžããŠã¿ãŸãã
RSpec.describe UsersController, type: :request do
describe 'GET /users' do
before do
create(:user, email: 'test@example.com', name: 'ãã¹ã')
get users_path
end
it { expect(response).to have_http_status(:ok) }
end
end
create(:user, email: 'test@example.com', name: 'ãã¹ã') ã®éšåã§ãããFactoryBotã«ç»é²ããŠããããšã§ããã£ãšæ¥œã«æžããããã«ãªããŸãã
3. describe, context, itãæžã
describe: ãã¹ãã®å¯Ÿè±¡
context: æ¡ä»¶ãç¶æ
it / example: ãã¹ã
åœããåã®ããšãªãã§ãããdescribe, context, itãæ£ãã䜿ããŸãããã
æ£ãã䜿ãããšã§ããã¹ãå¯Ÿè±¡ãšæ¡ä»¶ãæç¢ºã«ãªããã³ãŒãã®èŠéããè¯ããªããŸãã
ã³ãŒãã¯ãã³ãã³æ¹åãããŠãããã®ã§ãã
ã³ãŒã倿޿ããã¹ãã³ãŒãã®èŠéããæªããšãã¹ãã³ãŒãã远éããŠããããšãèŸããªããæŸçœ®ãããããšããããŸãã
ãã¹ãã³ãŒãã®èŠéããè¯ãããšã§ããã¹ããæžãããšãèŸããªããªããŸãã
æžããšãã®ã³ãã以äžã®ãã¹ãã³ãŒããäŸã«èª¬æããŸãã
RSpec.describe User, type: :model do
let(:user) { build(:user, email: 'test@example.com', name: 'ãã¹ã') }
it { expect(user.valid).to be_truthy }
context 'when email is empty' do
let(:user) { build(:user, email: '', name: 'ãã¹ã') }
it { expect(user.valid).to be_falsey }
end
end
RSpecã¯ãæç« ãšããŠèªãããšãã§ãããããªã£ãŠããŸãã
1ã€ç®ã®itã¯ããUserã¢ãã«ã®ãuser.valid ã®çµæã¯ãtrueã§ããããšãæåŸ
ããŸããããæå³ããŠããŸã
RSpec.describe User, type: :model do â ãUserã¢ãã«ãã«ã€ããŠã®ãã¹ãã§ããããšå®£èš
it { expect(user.valid).to be_truthy } â user.valid ã®çµæã¯ãtrueã§ããããšãæåŸ
ããŸãã
2ã€ç®ã®itã¯ããUserã¢ãã«ã®ãemailãemptyã®æãuser.valid ã®çµæã¯ãfalseã§ããããšãæåŸ
ããŸããããæå³ããŠããŸã
RSpec.describe User, type: :model do â ãUserã¢ãã«ãã«ã€ããŠã®ãã¹ãã§ããããšå®£èš
context 'when email is empty' do â ãemailãemptyã®æããšããç¶æ
ã衚ã
it { expect(user.valid).to be_truthy } â user.valid ã®çµæã¯ãfalseã§ããããšãæåŸ
ããŸãã
4. rubocopãå ¥ããŠã1ã€ã®é¢æ°ã®ã³ãŒãéãã§ããéãæžãããã·ã³ãã«ã«ãã
RSpecã®ããã«å°å ¥ããããã§ã¯ãããŸããã§ããããçµæçã«RSpecãæžããšãã«åœ¹ç«ã¡ãŸããã
以äžã¯ãããã³ãã©ããæºèŒã®ã³ãŒãã§ããã以äžã®ãããªã³ãŒããrubocopã¯èš±ããŸããã
ãããã£ããã¹ãã®æ·±ã颿°ãã³ãŒããé£ãªã£ãŠããã³ãŒãã«å¯ŸããRSpecãæžãããšæããšèºèºããŠããŸããŸãã
def save_and_save_file_and_send_mail(upload_file)
ActiveRecord::Base.transaction do
if save
if upload_file.present?
extension = upload_file.extname
File.open(Rails.root.join("public/myprofile/#{id}#{extension}"), 'w+') do |f|
f.write(upload_file.read)
end
end
if email.present?
UserMailer.send_mail(email, 'ãŠãŒã¶æ
å ±ãæŽæ°ããŸãã', self)
end
else
return false
end
end
end
以äžã®ããã«æžãæãããš
def save_and_save_file_and_send_mail(upload_file)
ActiveRecord::Base.transaction do
return false unless save
write_myprofile(upload_file)
send_mail
end
end
def write_myprofile(upload_file)
return if upload_file.present?
extension = upload_file.extname
File.open(Rails.root.join("public/myprofile/#{id}#{extension}"), 'w+') do |f|
f.write(upload_file.read)
end
end
def send_mail
return if email.present?
UserMailer.send_mail(email, 'ãŠãŒã¶æ
å ±ãæŽæ°ããŸãã', self)
end
ã³ãŒããèŠããããªããŸããããRSpecã容æã«ãªããŸããã
RSpec.describe User, type: :model do
describe '.save_and_save_file_and_send_mail' do
let(:user) { build(:user, email: 'test@example.com', name: 'ãã¹ã') }
it { expect(user.save_and_save_file_and_send_mail).to be_truthy }
end
describe '.write_myprofile' do
let(:user) { build(:user, email: 'test@example.com', name: 'ãã¹ã') }
let(:upload_file) { Rack::Test::UploadedFile.new(File.join(Rails.root, 'spec/fixtures/profile.png'), 'image/png') }
before do
user.write_myprofile(upload_file)
end
it { expect(Rails.root.join("public/myprofile/#{user.id}#.png")).to be_exist }
end
describe '.send_mail' do
let(:user) { build(:user, email: 'test@example.com', name: 'ãã¹ã') }
it { expect { user.send_mail }.to change(ActionMailer::Base.deliveries, :size).by(1) }
context 'when email is empty' do
let(:user) { build(:user, email: 'test@example.com', name: 'ãã¹ã') }
it { expect { user.send_mail }.to not_change(ActionMailer::Base.deliveries, :size).by(1) }
end
end
end
äžã€ã®é¢æ°ã®äžã§æ¡ä»¶åå²ããè€éã ã£ãã³ãŒããã·ã³ãã«ã«ãªããŸããã
5. matcherã¯èŠããªããŠè¯ã
RSpecã®matcherã¯ãæ°å€ãååšããŸãã
åæã¯ãmatcherã£ãŠäœã®ã¡ãªãããããã®ïŒãšæãããšãå€ã
ãããŸãã
ã¡ãã£ãšå°ã£ãæãå©ããŠãããã®ãmatcherã§ãã
matcherãäžã€äžã€ã¯èŠããªããŠããå¿
èŠã«ãªã£ããšããå°ã£ããšããmatcherã調ã¹ãŠå©çšã§ããã調ã¹ãŠã¿ãã ãã§ååã§ãã
- é åãæ¯èŒãããšãã颿°ã䞊ã³é ãæ ä¿ããŠããªããããããŸã«å€±æããæ
- ïŒè¡ã®ã³ãŒããçããããæ
- äŸå€ã®çºçã確èªãããæ
è¯ãRSpecã©ã€ããïŒ
æåŸã«
IVRyã§ã¯äžç·ã«åããŠããããšã³ãžãã¢ãåéäžã§ãïŒ
Discussion