测试一个组合的唯一性,我在数据库层面增加了组合 unique。 但是测试有问题:
def setup
@like = Like.new(liker_id: 1, liked_article_id: 1)
end
test "liker-id and liked-article-id unique" do
assert @like.valid?
assert @like.save
@other = @like.dup
assert_not @other.save
end
没有通过,但是在 Rails Console 中可以:
@like = Like.new(liker_id: 1, liked_article_id: 1)
@like.valid?
@like.save
@other = @like.dup
@other.save #失败
like.rb
class Like < ApplicationRecord
belongs_to :liker, class_name: "User"
belongs_to :liked_article, class_name: "Article"
validates :liker_id, presence: true
end
之前运行测试的时候出现了错误,让我运行 rails env=test 或者 env=development 大概这样,记不清了。 我运行了第一个,然后执行了迁移。
--------------------------------解决 按照 @lithium4010 说的:
liker liked article 必须关联上
测试环境数据库没有 id 为 1 的 liker 和 liked_article
进行如下修改:
def setup
@user = User.create(name:"kaka",email: "[email protected]",
password_digest: User.digest('password'))
@article = @user.articles.create(title: "mysq",content: "kakarot")
@like = Like.new(liker_id: @user.id, liked_article_id: @article.id)
end
test "liker-id and liked-article-id unique" do
Like.destroy_all
assert @like.valid?
assert @like.save
@other = Like.new(liker_id: @user.id, liked_article_id: @article.id)
assert_not @other.save
assert @user.destroy
assert @article.destroy
end
原谅我不知道这里固件应该怎么用。
我刚刚新建了一个跟你一样代码的项目做了测试,似乎就是你测试数据库里的 like 表的数据没有清除导致的。 like 里面添加 validates :liker_id, uniqueness: { scope: :liked_article_id} 然后我这里测试通过了
你测试改这样
def setup
@like = Like.new(liker_id: 1, liked_article_id: 1)
end
test "liker-id and liked-article-id unique" do
Like.destroy_all
@like.valid?
assert @like.valid?
assert @like.save
@other = Like.new(liker_id: 1, liked_article_id: 1)
assert_not @other.save
end
还是不行。。 还是原来的错误,都是 false 这样才能通过。
Like.destroy_all
assert_not @like.valid?
assert_not @like.save
@other = Like.new(liker_id: 1, liked_article_id: 1)
assert_not @other.save
会不会是我选择 env 的问题?
你改成这样
test "liker-id and liked-article-id unique" do
Like.destroy_all
@like.valid?
p "111!!!!#{@like.valid?}"
assert @like.valid?
assert @like.save
p "2222!!!!!#{@like.attributes}"
@other = Like.new(liker_id: 1, liked_article_id: 1)
p "3333!!!!#{@other.valid?}"
p "4444!!!!#{@other.errors.messages}"
assert_not @other.save
end
然后看看输出是什么?
rails test 之后,就只 Failure 没有其他错误信息了,话说还能这么用,我一直是在 console 里面,这么看。
p "111!!!!#{@like.valid?}"
p "@like errors: #{@like.errors.messages}"
添加一行,看看输出的是什么错误
"{:liker=>[\"must exist\"], :liked_article=>[\"must exist\"]}"
这不是在 new 的时候都有的吗?。。。
test "liker-id and liked-article-id unique" do
Like.destroy_all
@like.valid?
p "111!!!!#{@like.valid?}"
p "@like errors: #{@like.errors.messages}"
assert @like.valid?
assert @like.save
p "2222!!!!!#{@like.attributes}"
@other = Like.new(liker_id: 1, liked_article_id: 1)
p "3333!!!!#{@other.valid?}"
p "4444!!!!#{@other.errors.messages}"
assert_not @other.save
end
你测试用例改这样啊,看@like输出的的错误是什么
https://github.com/kai209209/like 我把我做的放到 github 里了,你看看跟你项目的 like 有没有什么区别吧
没什么区别,要说区别的话,只有 user 和 article
article.rb
has_many :passive_likes, class_name: "Like",
foreign_key: "liked_article_id",
dependent: :destroy
has_many :liked_article, through: :passive_likes
user.rb
has_many :active_likes, class_name: "Like",
foreign_key: "liker_id",
dependent: :destroy
has_many :liker, through: :active_likes
按照 @lithium4010 他说的,我改了之后好了。
def setup
@user = User.create(name:"kaka",email: "[email protected]",
password_digest: User.digest('password'))
@article = @user.articles.create(title: "mysq",content: "kakarot")
@like = Like.new(liker_id: @user.id, liked_article_id: @article.id)
end
test "liker-id and liked-article-id unique" do
Like.destroy_all
assert @like.valid?
assert @like.valid?
assert @like.save
@other = Like.new(liker_id: 1, liked_article_id: 1)
assert_not @other.save
assert @user.destroy
assert @article.destroy
end
有个 gem 可以测试完后自动删除测试数据的,你就不用写个 Like.destroy_all 上去了,而且测试数据一般在测试完后都是要删的