我正在構建一個非常小的Sinatra API,今天我開始爲它編寫測試。我正在使用RSpec和FactoryGirl。RSpec不應該失敗。爲什麼?
我有一個用戶模型,在控制器中我檢查註冊的用戶的電子郵件是否已經保存。如果保存,則返回402,否則我創建用戶並返回200.爲了測試此操作,我使用相同的參數對users
路由執行POST兩次,第一次檢查last_response.should be_ok
,因爲DB是空,所以我可以創建用戶,然後我有另一個測試,POST到users
路由與以前相同的參數,但期待last_response.should_not be_ok
,我得到一個200!所以測試失敗!
這是我的末日路線:
post '/users' do
user = User.where(email: params[:email]).first
if !user
user = User.create(email: params[:username], password_not_hashed: params[:password])
halt 200, {user:user}.to_json
end
halt 409, {error:"user already exists"}.to_json
end
這是我的測試:
describe 'Create User' do
include Rack::Test::Methods
params = {}
params['password'] = "username"
params['username'] = "[email protected]"
it "should create a user" do
post '/users', params
last_response.should be_ok
end
it "should fail to create a user because its duplicate user" do
post '/users', params
last_response.should_not be_ok
end
end
而且我得到一個失敗,因爲上次測試的響應是200我已經打印params
和last_response
與pp
這是我得到了什麼:
PARAMS:
{"password"=>"username", "username"=>"[email protected]"}
last_response
@block=nil,
@body=["{\"user\":{\"id\":null,\"email\":\"[email protected]\"}}"],
@body_string=nil,
@chunked=false,
@errors="",
@header=
{"Content-Type"=>"text/html;charset=utf-8",
"Content-Length"=>"52",
"X-XSS-Protection"=>"1; mode=block",
"X-Content-Type-Options"=>"nosniff",
"X-Frame-Options"=>"SAMEORIGIN"},
@length=52,
@original_headers=
{"Content-Type"=>"text/html;charset=utf-8",
"Content-Length"=>"52",
"X-XSS-Protection"=>"1; mode=block",
"X-Content-Type-Options"=>"nosniff",
"X-Frame-Options"=>"SAMEORIGIN"},
@status=200,
任何想法?!?!這讓我瘋狂!
編輯:
剛剛添加了一個活動記錄驗證(validates_uniqueness_of :email
),並在我的測試的輸出我得到如下:
Failure/Error: post '/users', params
ActiveRecord::RecordInvalid:
Validation failed: Email has already been taken
所以,這意味着有與已建立的用戶該電子郵件,所以我仍不明白爲什麼測試失敗,並且創建用戶的路線總是進入if !user
以下是代碼覆蓋率的輸出:
瘋了......我很迷茫!
編輯:
另外我有一個after all
rspec的鉤但不應該被importat因爲這一切都在測試後才能運行:
after :all do
ActiveRecord::Base.subclasses.each(&:delete_all)
end
如何在第14行更改條件?我一直在玩irb的用戶條件,我想知道它是否一直評估我們期望的方式。我仍然不確定。使用「if user.nil?」怎麼樣?代替?這似乎更精確一點。 –
同樣的問題...將其更改爲user.nil?並仍在進入! – Andres
添加打印語句或斷點時發生了什麼?您是否可以在測試執行期間檢查數據庫的狀態? –