簡體   English   中英

Michael Hartl Rails 教程:assert_not 與它應該做的完全相反,我不明白為什么

[英]Michael Hartl Rails tutorial: assert_not does exact opposite of what it should and I don't understand why

tl;dr 有效名稱不會因為測試失敗而寫入數據庫,而無效名稱會因為測試通過而寫入數據庫。

編輯:為了澄清項目和我的一般問題:如書中所述,此用戶模型設置為開始階段,以允許網站用戶最終登錄網站。 數據庫列將是“姓名”和“電子郵件”,每一行將是一個用戶(假設用戶名和電子郵件是有效的)。 為了進一步說明,我在下面編輯了我的原始帖子,所有編輯都以斜體顯示。

此外,請僅在您能我的帖子中那樣解釋代碼時才回復——不要建議添加額外的代碼以使其工作。 我正在工作的教科書斷言這段代碼應該按原樣工作,但它的評估結果似乎與它應該相反。 最后,如果您知道更詳細地解釋這一點的其他鏈接,那將很有幫助; 但是,我已經閱讀了apidockRoR API和大多數出現在 Google 搜索中的 SO 鏈接,但沒有一個有助於解釋這個問題。

我正在學習 Michael Hartl 的 Ruby on Rails 教程。 我在第 6 章進行驗證測試,但我一直在驗證名稱是否存在。 它似乎與教程所說的完全相反(即驗證無效的名稱條目),即使我完全按照教程進行了操作。 我還搜索了網絡和 SO 以獲取有關assert_not如何工作的更多詳細信息,但找不到任何有用的詳細信息。 這是我經歷的過程。

  1. 添加一個我們知道會失敗的測試:

     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 ,它將真值轉換為假值,並使測試失敗。

  1. 我們添加一個驗證測試:

     class User < ActiveRecord::Base validates :name, presence: true end

這為 User 模型設置了驗證規則,以確保:name對象具有內容並且不是 nil、空字符串或空格。 到目前為止還是不錯的。

  1. 這就是事情變得棘手的地方。 此時,表達式@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的無效值,從而允許將包含空格的名稱寫入數據庫,這與我們試圖實現的完全相反,即防止空白被寫入數據庫的名稱。

  1. 相反,我用一個有效的名稱計算出這個邏輯:

     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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM