程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Ruby on rails開發從頭來(windows)(二十二)-測試Controller

Ruby on rails開發從頭來(windows)(二十二)-測試Controller

編輯:關於JAVA

上次測試Modeul的問題還沒有解決,但是下面的還要繼續,這次來測試Controller。

1.在test\functional目錄下,rails已經為我們的controller生成了對應的測試文件,要注意application_controller不會生成測試文件。我們以控制登錄的LoginController為例,打開login_controller_test.rb,內容如下:

require File.dirname(__FILE__) + '/../test_helper'
require 'login_controller'
  
# Re-raise errors caught by the controller.class LoginController; def rescue_action(e) raise e end; end
  
class LoginControllerTest < Test::Unit::TestCase
def setup
@controller = LoginController.new
@request  = ActionController::TestRequest.new
@response  = ActionController::TestResponse.new
end
# Replace this with your real tests.def test_truth
assert true
end
end

我們看到,在setup方法裡,定義了三個對象@controller和@request和@response,這樣,我們就可以在不接入webserver或network的情況下進行測試了。

2.我們來把其中的test_truth方法替換成下面的代碼:

def test_index
get :index
assert_response :success
end

其中,get方法模擬發出一個web請求,請求的action是index,並且捕捉響應(response),然後由assert_response斷言來判斷響應是否成功。

現在運行測試:depot>ruby test/functional/login_controller_test.rb

會看到測試失敗了,命令行的輸出:

Expected response to be a <:success>, but was <302>
1 tests, 1 assertions, 1 failures, 0 errors

為什麼會這樣呢?回想一下,我們在前面的程序裡,在訪問index頁面時,要先判斷用戶是不是管理員。如果不是,就要跳轉到login頁面,在login_controller.rb裡:

before_filter :authorize, :except => :login

在application.rb文件裡,有authorize方法:

def authorize
unless session[:user_id]
flash[:notice] = "Please log in"
redirect_to(:controller => "login", :action => "login")
end
end

3.好了,知道了原因,現在再寫一個測試:

def test_index_without_user
get :index
assert_redirected_to :action => "login"
assert_equal "Please log in", flash[:notice]
end

上面的代碼裡,我們嘗試請求index這個action,並且使用斷言判斷是否重定向到login,再判斷flash[:notice]裡的內容。

再次運行測試,命令行的輸出如下:

Loaded suite test/functional/login_controller_test
Started
.Finished in 0.062 seconds.1 tests, 3 assertions, 0 failures, 0 errors

可以看到所有的斷言都通過了。

但是還有一個問題,就是根據代碼,我們只使用了兩個斷言,但是提示信息卻顯示有三個斷言,這個問題是什麼原因還不太清楚,但是現在並不影響我們繼續下面的內容。

4.在我們的login頁面上,用戶輸入名字和密碼後,點擊login按鈕,這些信息將會發送個login這個action,然後創建一個User的實例來讓用戶登入。

在login_controller.rb裡的login方法裡:

@user = User.new(params[:user])
logged_in_user = @user.try_to_login

現在,我們來測試login這個action,在login_controller_test.rb中添加方法:

def test_login_with_invalid_user
post :login, :user => {:name => 'fred', :password => 'opensesame'}
assert_response :success
assert_equal "Invalid user/password combination", flash[:notice]
end

大家一定看到了,這是使用了一個不存在的用戶名和密碼來測試login。

運行測試,輸出結果如下:

Finished in 0.609 seconds.2 tests, 5 assertions, 0 failures, 0 errors

和上一個測試方法相對的,這裡代碼裡是兩個斷言,根據輸出也是兩個,挺奇怪的事情。

5.測試了不存在的用戶,現在我們來測試用戶存在的情況。

修改fixtures目錄下的users.yml文件,我們還使用上面的用戶名和密碼:

# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
fred:
 id: 1
 name: fred
 hashed_password: <%= Digest::SHA1.hexdigest('abracadabra') %>

然後給login_controller_test.rb添加fixtures :users,指定使用users.yml文件。

再添加方法:

def test_login_with_valid_user
post :login, :user => {:name => 'fred', :password => 'abracadabra'}
assert_redirected_to :action => "index"
assert_not_nil(session[:user_id])
user = User.find(session[:user_id])
assert_equal 'fred', user.name
end

在這裡方法裡,我們指定了和yml文件中定義的用戶名相一致的數據,並且判斷是否定位到index,再判斷用戶的id是否已經保存在session中。

根據前面測試Model時候的內容,我們在yml文件中定義的數據會被加入到數據庫中,這樣,這個方法裡的三個斷言都應該通過才對。

OK了,運行測試,輸出結果:

Finished in 0.125 seconds.3 tests, 8 assertions, 0 failures, 0 errors

嗯,所有的斷言都通過了。

好了,這次就到這裡。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved