【发布时间】:2016-01-28 20:54:26
【问题描述】:
这就是我初始化实例变量的方式:
context "when the inviter is being deleted and invited HAS accepted invitation" do
before :each do
@user1 = create(:user, gender: 0)
@user2 = create(:user)
@membership1 = create(:membership, member: nil, family_tree: @user1.family_tree, inviter: @user1, invited: @user2, relation: "sister", relative_type: 1)
@membership2 = create(:membership, member: nil, family_tree: @user2.family_tree, inviter: @user2, invited: @user1, relation: "brother", relative_type: 1)
@connection = create(:connection, inviter_membership: @membership1, invited_membership: @membership2, inviter_user: @user1, invited_user: @user2, request_status: 1)
sign_in @user1
end
然而,当我运行这个测试时:
it "should NOT delete the inviter_membership record" do
inviter_membership = @membership1
delete :destroy, id: @user1
expect(Membership.find(inviter_membership.id)).to be inviter_membership
end
我收到此错误:
ActiveRecord::RecordNotFound: Couldn't find Membership with 'id'=1441
当我在 PRY 控制台上探索我的数据库时,由于此测试失败而生成,这些是我的结果:
[1] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> inviter_membership
=> #<Membership id: nil, family_tree_id: 31704, user_id: 13101, created_at: "2016-01-28 20:46:58", updated_at: "2016-01-28 20:46:58", relation: "sister", member_id: nil, invited_id: 13102, relative_type: 1>
[2] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership1
=> #<Membership id: nil, family_tree_id: 31704, user_id: 13101, created_at: "2016-01-28 20:46:58", updated_at: "2016-01-28 20:46:58", relation: "sister", member_id: nil, invited_id: 13102, relative_type: 1>
不是初始的membership.id: nil 值。当我检查我的其他记录时,我看到了类似的东西:
[5] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @user1
=> #<User id: nil, email: "eleanore.keeling@lindgrenhettinger.net", encrypted_password: "$2a$04$lROCfnS8rHf3Y2CKp0Ozw.9zsqa4rXTmxU6QvpGUm9S...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: "2016-01-28 20:46:58", updated_at: "2016-01-28 20:46:58", first_name: "Murphy", confirmation_token: nil, confirmed_at: "2016-01-28 20:46:56", confirmation_sent_at: nil, unconfirmed_email: nil, invitation_relation: "a", avatar: nil, invitation_token: nil, invitation_created_at: nil, invitation_sent_at: nil, invitation_accepted_at: nil, invitation_limit: nil, invited_by_id: nil, invited_by_type: nil, invitations_count: 0, bio: "Facere consequatur odio recusandae aut ipsa repudi...", last_name: "Haag", gender: 0, birthday: nil>
[6] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @user2
=> #<User id: nil, email: "dillon.feest@jacobson.biz", encrypted_password: "$2a$04$ju0c8gr/RUaPeRNneh5rVOAN3QtUoMEzy9UwM4.a.D3...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: "2016-01-28 20:46:58", updated_at: "2016-01-28 20:46:58", first_name: "Neva", confirmation_token: nil, confirmed_at: "2016-01-28 20:46:56", confirmation_sent_at: nil, unconfirmed_email: nil, invitation_relation: "voluptatem", avatar: nil, invitation_token: nil, invitation_created_at: nil, invitation_sent_at: nil, invitation_accepted_at: nil, invitation_limit: nil, invited_by_id: nil, invited_by_type: nil, invitations_count: 0, bio: "Reiciendis optio mollitia et vel. Adipisci odit el...", last_name: "Rippin", gender: 1, birthday: nil>
[7] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership2
=> #<Membership id: nil, family_tree_id: 31706, user_id: 13102, created_at: "2016-01-28 20:46:58", updated_at: "2016-01-28 20:46:58", relation: "brother", member_id: nil, invited_id: 13101, relative_type: 1>
不确定是否与保存有关,但奇怪的是我的 @connection 值实际上有一个有效的 id:
[4] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @connection
=> #<Connection id: 1892, membership_id: 1441, sent_at: "2016-01-23 01:58:47", responded_at: "2016-02-12 11:17:20", send_limit: 5, times_sent: 1, removed_at: "2016-01-28 20:46:58", created_at: "2016-01-28 20:46:58", updated_at: "2016-01-28 20:46:58", request_status: 1, invited_membership_id: 1442, invited_user_id: 13102, inviter_user_id: 13101>
我唯一能想到的是,在我的代码中,我实际上调用了connection.update(...),相当于这个@connection。那么也许那个电话会保存记录?
如果是这种情况,我如何在 Rspec 中保存我的记录(我想要吗??)或者我如何在数据库中找到该记录?我需要确认它没有被删除。
编辑 1
如果我在 @membership1 初始化中使用 build 而不是 create 并深入研究它,这就是我得到的:
[1] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership1
=> #<Membership id: nil, family_tree_id: 31799, user_id: 13146, created_at: "2016-01-28 21:08:09", updated_at: "2016-01-28 21:08:09", relation: "sister", member_id: nil, invited_id: 13147, relative_type: 1>
[2] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> inviter_membership
=> #<Membership id: nil, family_tree_id: 31799, user_id: 13146, created_at: "2016-01-28 21:08:09", updated_at: "2016-01-28 21:08:09", relation: "sister", member_id: nil, invited_id: 13147, relative_type: 1>
[3] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership1.valid?
=> true
[5] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership1.errors
=> #<ActiveModel::Errors:0x007fbd2f9fb458
@base=
#<Membership id: nil, family_tree_id: 31799, user_id: 13146, created_at: "2016-01-28 21:08:09", updated_at: "2016-01-28 21:08:09", relation: "sister", member_id: nil, invited_id: 13147, relative_type: 1>,
@messages={}>
编辑 2
所以这是奇怪的事情,我在顶部的before :each 中放了一个binding.pry,以检查在将执行发送到每个it 块之前生成的值。这些值确实有 ID。
51: @membership1 = build(:membership, member: nil, family_tree: @user1.family_tree, inviter: @user1, invited: @user2, relation: "sister", relative_type: 1)
52: @membership2 = create(:membership, member: nil, family_tree: @user2.family_tree, inviter: @user2, invited: @user1, relation: "brother", relative_type: 1)
53: @membership3 = build_stubbed(:membership)
54: @connection = create(:connection, inviter_membership: @membership1, invited_membership: @membership2, inviter_user: @user1, invited_user: @user2, request_status: 1)
55: sign_in @user1
=> 56: binding.pry
57: end
58:
59: it "should confirm that inviter_membership has nil member_id" do
60: expect(@user1.inviter_memberships.first.member).to be nil
61: end
[1] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership1
=> #<Membership id: 1474, family_tree_id: 31878, user_id: 13183, created_at: "2016-01-28 21:37:38", updated_at: "2016-01-28 21:37:38", relation: "sister", member_id: nil, invited_id: 13184, relative_type: 1>
[2] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership2
=> #<Membership id: 1473, family_tree_id: 31880, user_id: 13184, created_at: "2016-01-28 21:37:38", updated_at: "2016-01-28 21:37:38", relation: "brother", member_id: nil, invited_id: 13183, relative_type: 1>
[3] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership3
=> #<Membership id: 1007, family_tree_id: 1001, user_id: 1003, created_at: nil, updated_at: nil, relation: "possimus", member_id: 1006, invited_id: 1005, relative_type: 0>
但是,在我关注的it 块中,它似乎覆盖了每个实例变量的id 值,除了我刚刚使用build_stubbed 方法而不是create 添加的值:
71: inviter_membership = @membership1
72: delete :destroy, id: @user1
=> 73: expect(Membership.find(inviter_membership.id)).to be inviter_membership
74: end
75:
76: it "should create a member record with inviter_user's info" do
77: expect {
78: delete :destroy, id: @user1
ActiveRecord::RecordNotFound: Couldn't find Membership with 'id'=1478
from /gems/activerecord-.1.14/lib/active_record/relation/finder_methods.rb:320:in `raise_record_not_found_exception!'
[1] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership1
=> #<Membership id: nil, family_tree_id: 31886, user_id: 13187, created_at: "2016-01-28 21:38:23", updated_at: "2016-01-28 21:38:23", relation: "sister", member_id: nil, invited_id: 13188, relative_type: 1>
[2] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership2
=> #<Membership id: nil, family_tree_id: 31888, user_id: 13188, created_at: "2016-01-28 21:38:23", updated_at: "2016-01-28 21:38:23", relation: "brother", member_id: nil, invited_id: 13187, relative_type: 1>
[3] pry(#<RSpec::ExampleGroups::UsersController::DELETEDestroy::WhenTheInviterIsBeingDeletedAndInvitedHASAcceptedInvitation>)> @membership3
=> #<Membership id: 1021, family_tree_id: 1015, user_id: 1017, created_at: nil, updated_at: nil, relation: "at", member_id: 1020, invited_id: 1019, relative_type: 0>
什么可以覆盖it 块中的id 值?
编辑 3
所以身份验证发生了一些奇怪的事情。
如果我执行sign_in @user2,那么失败的测试现在通过了。
这是以sign_in @user1 失败但以sign_in @user2 通过的测试:
it "should NOT delete the inviter_membership record" do
expect {
delete :destroy, id: @user1
}.not_to change(Membership,:count)
end
我尝试完全注释掉 sign_in 行,这也导致上述测试通过。
奇怪的是,在我的 user 模型上,我有一个 before_destroy :callback,当我在该方法中放置一个 binding.pry 时,它不会在该测试中执行,无论是失败还是通过测试。所以看起来回调没有被调用,这超级奇怪。
【问题讨论】:
-
你可以尝试使用 build 的工厂为 members1,然后调用 members1.valid?其次是membership1.errors ?
-
@PeterdeRidder 完成。我用结果更新了问题。
-
您可以忽略我的第一条评论,因为如果无法创建工厂,FactoryGirl 的创建就会引发错误。不幸的是,我没有时间研究它,但从一瞥之下,现在你可以使用 build、create 和 build_stubbed 来获得 3 个成员资格。如果你想查询成员资格,你应该使用 create。
-
关于覆盖 id 的小提示:每次运行每个块之前,您都从一个空的成员资格表开始并创建新的成员资格。对于每个示例(它),您都有 3 个新的会员 ID。关于 FactoryGirl 中的 build、build_stubbed 和 create,只有 create 将对象存储在数据库中。所以如果你有任何查询,你应该使用create,否则找不到记录。另一个提示:如果您想知道哪些对象持久化,只需在您的示例中调用 Membership.all.map(&:attributes)。
-
是的...我主要使用
create,但我开始探索其他人,因为您建议build:) 我会尝试建议回复:Membership.all。
标签: ruby-on-rails ruby-on-rails-4 rspec rspec-rails