環境
Ruby 3.0.2
Rails 6.1.4.1
前提
現在のQiitaの記事投稿状況をSlackに通知してくれるbotがあり、そのテストを書きたい
テストのやり方
jsonのダミーデータを作成して適当なプロジェクト内に保存しておく。
slackの方も同じように作成。
qiita_user_response.json
{
"description":"未経験から転職して3ヶ月目のサーバーサイドエンジニア\r\n12月10日までに100記事投稿を目標にしています!",
"facebook_id":"",
"followees_count":0,
"followers_count":1,
"github_login_name":null,
"id":"kat0",
"items_count":20,
"linkedin_id":"",
"location":"",
"name":"",
"organization":"",
"permanent_id":XXXXX,
"profile_image_url":"https://secure.gravatar.com/avatar/XXXXXXXXXXXX",
"team_only":false,
"twitter_screen_name":null,
"website_url":""
}
spec.rb
require 'rake_helper'
require 'webmock/rspec'
describe 'namespace名:task名' do
subject(:task) { Rake.application['namespace名:task名'] }
let!(:qiita_request_stub) do
WebMock.stub_request(:get, "https://qiita.com/api/v2/users/XXXXX")
.to_return(
body: File.new("spec/models/data/qiita_user_response.json"),
status: 200,
headers: { 'Content-Type' => 'application/json' }
)
end
let!(:slack_request_stub) do
WebMock.stub_request(:post, "https://slack.com/api/chat.postMessage")
.to_return(
body: File.new("spec/models/data/slack_response.json"),
status: 200,
headers: { 'Content-Type' => 'application/json' }
)
end
it 'botが投稿状況を通知すること' do
travel_to Time.zone.local(2021, 10, 11) do
task.invoke
expect(
a_request(:post, "https://slack.com/api/chat.postMessage").with { |req|
hash = Hash[URI.decode_www_form(req.body)]
hash["channel"] == "#チャンネル名" && hash["text"] == "本日までの加藤さんの記事投稿数は20記事になりました!!\n目標まであと80記事、1日1.9記事ペースで目標達成!\n引き続きがんばれ〜!\n"
}
).to have_been_made
expect(slack_request_stub).to have_been_requested
expect(qiita_request_stub).to have_been_requested
end
end
- サービスのAPIのリクエストスタブを作成し、bodyに最初に作成したjsonファイルを指定する
-
task.invoke
でtaskを実行し、a_request
でAPI叩いたときの期待する値が作られているかテスト -
hash = Hash[URI.decode_www_form(req.body)]
SlackのAPIを叩いたときのrequest.bodyの中身をいい感じにhashで返してくれるようにしている - テストコード内に
WebMock.enable!
を書いてある記事がたくさんあったがなくてもwebmockは有効になっていそうだった
参考