![](/img/trans.png)
[英]Why does the Home Page break with failed micropost submission - Michael Hartl Rails tutorial
[英]Michael Hartl Rails tutorial: assert_not does exact opposite of what it should and I don't understand why
tl;dr 有效名稱不會因為測試失敗而寫入數據庫,而無效名稱會因為測試通過而寫入數據庫。
編輯:為了澄清項目和我的一般問題:如書中所述,此用戶模型設置為開始階段,以允許網站用戶最終登錄網站。 數據庫列將是“姓名”和“電子郵件”,每一行將是一個用戶(假設用戶名和電子郵件是有效的)。 為了進一步說明,我在下面編輯了我的原始帖子,所有編輯都以斜體顯示。
此外,請僅在您能像我的帖子中那樣解釋代碼時才回復——不要建議添加額外的代碼以使其工作。 我正在工作的教科書斷言這段代碼應該按原樣工作,但它的評估結果似乎與它應該相反。 最后,如果您知道更詳細地解釋這一點的其他鏈接,那將很有幫助; 但是,我已經閱讀了apidock 、 RoR API和大多數出現在 Google 搜索中的 SO 鏈接,但沒有一個有助於解釋這個問題。
我正在學習 Michael Hartl 的 Ruby on Rails 教程。 我在第 6 章進行驗證測試,但我一直在驗證名稱是否存在。 它似乎與教程所說的完全相反(即驗證無效的名稱條目),即使我完全按照教程進行了操作。 我還搜索了網絡和 SO 以獲取有關assert_not
如何工作的更多詳細信息,但找不到任何有用的詳細信息。 這是我經歷的過程。
添加一個我們知道會失敗的測試:
require 'test_helper' class UserTest < ActiveSupport::TestCase def setup @user = User.new(name: "Example User", email: "user@example.com") end # resolves to true and passes test "should be valid" do assert @user.valid? end test "name should be present" do @user.name = " " assert_not @user.valid? end end
到現在為止還挺好。 我完全理解這段代碼,雖然第二個測試的措辭很尷尬,但我解釋了assert_not @user.valid?
像這樣工作: @user.valid?
評估為真,因為尚未設置驗證,因此測試認為包含所有空格的名稱是有效的。 這之前是一個assert_not
,它將真值轉換為假值,並使測試失敗。
我們添加一個驗證測試:
class User < ActiveRecord::Base validates :name, presence: true end
這為 User 模型設置了驗證規則,以確保:name
對象具有內容並且不是 nil、空字符串或空格。 到目前為止還是不錯的。
這就是事情變得棘手的地方。 此時,表達式@user.valid?
在我們的測試中應該(並且確實)評估為 false,因為驗證規則不允許:name
中只有空格。 我在此代碼旁邊添加了注釋,以幫助我了解在此過程中分配和評估的值:
test "name should be present" do @user.name = " " # => name: " " email: "example@example.com" assert_not @user.valid? # => assert_not false => true end
@user.valid?
計算結果為 false,這使得整個assert_not
表達式的計算結果為 true,因此測試通過。 在偽代碼中,這一行可以這樣翻譯: assert_not (is the user valid? no)
==> assert_not(false)
==> true
。 類似地,“我們不斷言用戶是假的”,其計算結果為真。
這就是我的問題所在:測試傳遞了:name
的無效值,從而允許將包含空格的名稱寫入數據庫,這與我們試圖實現的完全相反,即防止空白被寫入數據庫的名稱。
相反,我用一個有效的名稱計算出這個邏輯:
test "name should be present" do # => name: "Example User" email: "example@example.com" assert_not @user.valid? # assert_not true => false end
在這種情況下,因為@user.valid?
評估為真(因為“示例用戶”是有效名稱), assert_not @user.valid?
評估為 false,測試失敗,我們的有效名稱不會寫入數據庫。 在偽代碼中,這一行可以這樣翻譯: assert_not (is the user valid? yes)
==> assert_not(true)
==> false
。 類似地,“我們不斷言用戶是真的”,其計算結果為假。 由於測試評估為假(即使用戶名為真/有效),此有效名稱不會寫入數據庫。
如果有人能解釋這有什么意義,我將不勝感激,並且詳細的答案會引導我完成它會更好。
該測試傳遞了一個無效的 :name 值,從而允許將包含空格的名稱寫入數據庫...
如果后面的表達式@user.valid?
assert_not返回真(與測試通過相同) @user.valid?
,返回假。 實際上,第 3 節中的測試說:我們沒有斷言用戶是有效的。 由於該期望/斷言是正確的,它返回 true 並且測試通過。 沒有任何東西被保存到數據庫中。
您可以在添加字符串“”時添加驗證,該字符串由兩個空格組成
class User < ActiveRecord::Base
validates :name, presence: true, allow_blank: false
validate :name_of_valid
def name_of_valid
self.errors.add :base, 'My string can not be empty' if self.name == " "
end
end
進而
test "name should be present" do
@user.name = " "
# => name: " " email: "example@example.com"
assert_not @user.valid?
# => assert_not true
end
我有同樣的問題。 只有presence: true
測試失敗,當我添加allow_blank: false
它通過。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.