使用 RSpec 在 Rails 上测试 Ruby 中单个模型的多个关联
Test many associations from a single model in Ruby on Rails using RSpec
我有一个用户模型和一个项目模型。
一个用户可以创建多个项目,而一个项目只有一个所有者,可以有多个成员。
#app/models/user.rb
class User < ApplicationRecord
has_secure_password
has_many :projects
has_and_belongs_to_many :projects
end
#app/models/project.rb
class Project < ApplicationRecord
belongs_to :user
has_and_belongs_to_many :users
end
这将创建一个数据库 tables 是这样的:
create_table "projects", force: :cascade do |t|
t.string "name"
t.integer "user_id" #id of the owner of the projects
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["user_id"], name: "index_projects_on_user_id"
end
create_table "projects_users", force: :cascade do |t|
t.integer "user_id" #id of the member of the project
t.integer "project_id" #project that the member joined
t.index ["project_id"], name: "index_projects_users_on_project_id"
t.index ["user_id"], name: "index_projects_users_on_user_id"
end
create_table "users", force: :cascade do |t|
t.string "first_name"
t.string "last_name"
t.string "email"
t.string "password_digest"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
其中 projects_users
table 是为 has_and_belongs_to_many
关联创建的 junction/bridge table。
但是每当我 运行 使用 rspec 进行测试并且应该只有其中一个成功时,另一个失败,因为在 user.rb
文件中 :projects
被定义了两次。
#spec/models/user_spec.rb
require 'rails_helper'
RSpec.describe User, :type => :model do
context 'associations' do
it { should have_many(:projects) } #error
it { should have_and_belong_to_many(:projects) } #success
end
end
错误是Failure/Error: it { should have_many(:projects) }
Expected User to have a has_many association called projects (actual association type was has_and_belongs_to_many)
#spec/models/project_spec.rb
require 'rails_helper'
RSpec.describe Project, :type => :model do
context 'associations' do
it { should belong_to(:user) } #success
it { should have_and_belong_to_many(:users) } #success
end
end
如何正确测试一个模型中的多个关联?
根据共享的描述,我能够使用下面提到的代码段测试 has_many:
RSpec.describe User, :type => :model do
context 'associations' do
it "should have many projects" do
subject { described_class.new }
assc = described_class.reflect_on_association(:projects)
expect(assc.macro).to eq :has_many
end
end
end
那么 has_man_belongs_to_many 部分的答案只需更改为这样的内容:
RSpec.describe Project, :type => :model do
context 'associations' do
it 'should have many and belongs to many Projects' do
subject {described_class.new }
response = described_class.reflect_on_association(:projects)
expect(assc.macro).to eq :has_and_belongs_to_many
end
end
end
我有一个用户模型和一个项目模型。
一个用户可以创建多个项目,而一个项目只有一个所有者,可以有多个成员。
#app/models/user.rb
class User < ApplicationRecord
has_secure_password
has_many :projects
has_and_belongs_to_many :projects
end
#app/models/project.rb
class Project < ApplicationRecord
belongs_to :user
has_and_belongs_to_many :users
end
这将创建一个数据库 tables 是这样的:
create_table "projects", force: :cascade do |t|
t.string "name"
t.integer "user_id" #id of the owner of the projects
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["user_id"], name: "index_projects_on_user_id"
end
create_table "projects_users", force: :cascade do |t|
t.integer "user_id" #id of the member of the project
t.integer "project_id" #project that the member joined
t.index ["project_id"], name: "index_projects_users_on_project_id"
t.index ["user_id"], name: "index_projects_users_on_user_id"
end
create_table "users", force: :cascade do |t|
t.string "first_name"
t.string "last_name"
t.string "email"
t.string "password_digest"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
其中 projects_users
table 是为 has_and_belongs_to_many
关联创建的 junction/bridge table。
但是每当我 运行 使用 rspec 进行测试并且应该只有其中一个成功时,另一个失败,因为在 user.rb
文件中 :projects
被定义了两次。
#spec/models/user_spec.rb
require 'rails_helper'
RSpec.describe User, :type => :model do
context 'associations' do
it { should have_many(:projects) } #error
it { should have_and_belong_to_many(:projects) } #success
end
end
错误是Failure/Error: it { should have_many(:projects) }
Expected User to have a has_many association called projects (actual association type was has_and_belongs_to_many)
#spec/models/project_spec.rb
require 'rails_helper'
RSpec.describe Project, :type => :model do
context 'associations' do
it { should belong_to(:user) } #success
it { should have_and_belong_to_many(:users) } #success
end
end
如何正确测试一个模型中的多个关联?
根据共享的描述,我能够使用下面提到的代码段测试 has_many:
RSpec.describe User, :type => :model do
context 'associations' do
it "should have many projects" do
subject { described_class.new }
assc = described_class.reflect_on_association(:projects)
expect(assc.macro).to eq :has_many
end
end
end
那么 has_man_belongs_to_many 部分的答案只需更改为这样的内容:
RSpec.describe Project, :type => :model do
context 'associations' do
it 'should have many and belongs to many Projects' do
subject {described_class.new }
response = described_class.reflect_on_association(:projects)
expect(assc.macro).to eq :has_and_belongs_to_many
end
end
end