A flash test
前一節提到的 flash 錯誤顯示是個小 bug,根據之前提到的測試法則,我們應該寫個測試來捕捉錯誤然後防止不會再發生這種 bug。所以我們要為登入表單的提交處理,寫個簡短的整合測試:
$ rails generate integration_test users_login
invoke test_unit
create test/integration/users_login_test.rb
測試的步驟是:
- 瀏覽登入頁面
- 確認登入表單正確渲染
- 使用無效的 params hash 對登入頁面發出 POST 請求
- 確認登入頁面重新渲染,並且會出現 flash 的錯誤訊息
- 瀏覽其他頁面(例如首頁)
- 確認 flash 的訊息不會出現在其他頁面
完整程式碼如下:
test/integration/users_login_test.rb
require 'test_helper'
class UsersLoginTest < ActionDispatch::IntegrationTest
test "login with invalid information" do
get login_path
assert_template 'sessions/new'
post login_path, session: { email: "", password: "" }
assert_template 'sessions/new'
assert_not flash.empty?
get root_path
assert flash.empty?
end
end
執行測試,會顯示失敗(Red):
$ bundle exec rake test TEST=test/integration/users_login_test.rb
TEST=test/integration/users_login_test.rb 這段是只測試指定的測試檔案。
為了要通過測試,必須把 flash 換成 flash.now,這是專門用在 render 頁面上的 flash 訊息。和 flash 不不的是,flash.now 的內容會在下一個請求時(get root_path)消失。
完整程式碼如下:
app/controllers/sessions_controller.rb
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
# Log the user in and redirect to the user's show page.
else
flash.now[:danger] = 'Invalid email/password combination'
render 'new'
end
end
執行測試,就會通過了(Green):
$ bundle exec rake test TEST=test/integration/users_login_test.rb
$ bundle exec rake test