ruby-on-rails - rails minitest 让我发疯 PG::UniqueViolation 错误
问题描述
有一半的时间我可以运行我的测试。另一半由于违反唯一性而失败,我无法找到其来源。现在我处于后半段。我的错误是这样的:
ItemTest#test_valid_setup:
ActiveRecord::RecordNotUnique: PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_blobs_on_user_id_and_item_id"
DETAIL: Key (user_id, item_id)=(1, 1) already exists.
: INSERT INTO "blobs" ("user_id", "item_id", "amount", "active", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id"
test/models/item_test.rb:15:in `setup'
我有一个factories.rb
:
FactoryBot.define do
factory :user, aliases: [:owner] do
email "test@test.com"
username "test"
end
factory :item do
owner
image { loads file etc... }
price 100
...
end
factory :blob, aliases: [:wanted, :collateral] do
user
item
amount 0
active true
end
end
我的item_test.rb
require 'test_helper'
require 'support/database_cleaner'
class ItemTest < Minitest::Test
def setup
DatabaseCleaner.start
#create users
@user1 = FactoryBot.create(:user, email: "a@pear.com", username: "barnyard")
@user2 = FactoryBot.create(:user, email: "bo@ichi.com", username: "ponygrl")
@user3 = FactoryBot.create(:user, email: "ho@ho.com", username: "hon")
#create items
@item1 = FactoryBot.create(:item, owner: @user1)
@item2 = FactoryBot.create(:item, owner: @user2, price: 101)
@item3 = FactoryBot.create(:item, owner: @user3, price: 102)
#create blobs
@blob1 = FactoryBot.create(:blob, user: @user1, item: @item1, amount: @item1.price, active: false)
@blob2 = FactoryBot.create(:blob, user: @user2, item: @item2, amount: @item2.price, active: false)
@blob3 = FactoryBot.create(:blob, user: @user3, item: @item3, amount: @item3.price, active: false)
end
def teardown
DatabaseCleaner.clean
end
end
然后一个item.rb
class Item < ApplicationRecord
after_create :create_blobs
private
def create_blobs
blob = Blob.new(user_id: self.owner.id, item_id: self.id, amount: self.price)
blob.save
end
end
一点背景: AUser
创建 an Item
,后者又Blob
在 an中创建 a ,after_create
其amount
参数设置为Item
's的值price
。我不知道如何在 minitest 中运行 after_create,所以我模拟了Blob
setup 中的数据以从Item
.
我可以看到错误来自第 15 行item_test.rb
,但我不明白为什么。我正在创建Users
,然后是Items
,然后是ERRORBlobs
。我理解为什么(我对用户和项目的组合有一个数据库级别的唯一性约束),但不理解如何(因为从我所看到的,我没有创建这些-在测试中创建它们时Blobs
没有after_create
调用) Item
,我怀疑这与我写这篇文章的方式有关。
在我看来很自然地得出结论,DatabaseCleaner.start
并且DatabaseCleaner.clean
在测试运行和结束时都启动和清理旧的测试数据,但显然情况并非如此。我开始专门使用它来避免我以前遇到的这个问题。所以我 db:drop db:create 和 db:schema:load,但我又遇到了同样的问题。如果不是这样,那就是对用户名、电子邮件等的唯一性侵犯……长话短说,这个错误是怎么回事?
对不起,如果这太令人困惑了。
编辑:如果我取消注释并将通过该回调创建after_create
的对象的所有方法引用替换为在我的测试设置中创建的对象,则测试通过。但我真的不喜欢那样做。blob
blobs
解决方案
要么取消注释after_create
并引用测试对象,要么删除测试对象并通过编写返回 blobowned_by user 和 item 的方法来引用每个 blob,这样您就可以编写@item.blob
,并让它返回相关的blob
。
推荐阅读
- apache-kafka - Kafka 自定义 AuthenticateCallbackHandler
- javascript - 在滚动时将导航粘贴到网页顶部不起作用
- qt5 - Overo Yocto Qt5 部署
- ios - 如何从自定义视图单元重新加载数据?
- python - 如何在 tensorflow MLP Mnist 示例中预测我的测试图像
- github - Emmet 与 Atom 自动完成冲突
- c# - 我正在尝试建立一个国际象棋游戏并且瓷砖出现在错误的位置
- python-2.7 - python由用户写入输入而没有脏字符
- textmate - 具有多个值的范围属性
- c++ - 具有使用 operator<< 并打印错误值 c++ 的类的程序