tl; dr有效名称不会写入数据库,因为测试失败,并且因为测试通过而无效的名称会写入数据库。
编辑: 有关项目和我的问题的一般说明:如本书所述,此用户模型设置为允许网站用户最终登录的开始阶段进入一个网站。数据库列将是" name"和"电子邮件",每行将是一个用户(假设用户名和电子邮件有效)。我已编辑了以下原始帖子以进一步说明,所有修改均以斜体显示。
此外,如果您可以在我的帖子中解释代码 ,请回复 - 请勿建议添加其他代码以使其正常工作。我工作的教科书声称这段代码应该按原样运行,但它似乎正在评估它应该相反的情况。最后,如果您知道其他链接可以更详细地解释这一点,那么这很有帮助;但是,我已经阅读了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?
求值为true,因为没有设置验证,所以测试认为所有空格的名称都是有效的。这之前是assert_not
,它将true值转换为false,并使测试失败。
我们添加了验证测试:
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,从而测试通过。 在伪代码中,这一行可以这样翻译:{{1}} ==&gt; assert_not (is the user valid? no)
==&gt; assert_not(false)
。类似地,&#34;我们没有断言用户是假的&#34;,其评估为真。
这就是我的问题所在:测试传递了true
的无效值,因此允许将包含空格的名称写入数据库,而这恰好与我们正在尝试实现,即阻止将空白名称写入db。
相反,我用有效名称计算了这个逻辑:
:name
在这种情况下,由于test "name should be present" do
# => name: "Example User" email: "example@example.com"
assert_not @user.valid?
# assert_not true => false
end
的计算结果为true(因为&#34;示例用户&#34;是有效名称),@user.valid?
计算结果为false,测试失败,并且我们的有效名称没有写入数据库。 在伪代码中,这一行可以这样翻译:{{1}} ==&gt; assert_not @user.valid?
==&gt; assert_not (is the user valid? yes)
。类似地,&#34;我们没有声明用户是真的&#34;,其评估为false。由于测试评估为false(即使使用真实/有效的用户名),因此不会将此有效名称写入数据库。
如果有人可以解释这有什么意义,我会非常感激,并且详细解答让我走过它会更好。
答案 0 :(得分:3)
如果后面的表达式测试传递的值无效 :name,因此允许写入由空格组成的名称 到数据库...
@user.valid?
返回false,则assert_not返回true(与测试传递相同)。实际上,第3节中的测试说:我们并未断言用户是有效的。由于该期望/断言是正确的,它返回true并且测试通过。没有任何东西保存到数据库中。
答案 1 :(得分:0)
您可以在添加字符串时添加验证&#34; &#34;包含两个空格
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
答案 2 :(得分:0)
我有同样的问题。仅对于presence: true
,测试失败,当我添加allow_blank: false
时,测试通过。