使用 rspec + shoulda-matchers 进行测试
testing with rspec + shoulda-matchers
我以前从未写过自己的测试,我刚刚完成模型关联并迁移它们,所以现在我想测试它们。我已经添加到 gemfile 并在 group :test
下安装了 gem 'shoulda-matchers', '~> 3.0'
,在 group :development, :test
下安装了 gem 'rspec-rails', '~> 3.0'
。将 shoulda-matchers 的配置添加到 spec/rails_helper.rb 中。下一步是什么?测试文件将放入哪个目录?编写 shoulda 匹配器的句法规则是什么,与 rspec 相同?例如,我如何检查该关联是否正常工作?
class Artist < ApplicationRecord
has_many events, :through => :lineups
end
像这样?
describe Artist do
it { should have_many(:events).through(:lineups) }
end
我觉得不错 - 这是另一个使用 class Listing
测试关联和验证的示例。
class Listing < ActiveRecord::Base
#Associations
belongs_to :user
belongs_to :category, inverse_of: :listings
has_many :photos, dependent: :destroy
has_many :watches
has_many :watchers, -> { uniq }, :through => :watches
has_many :offers, dependent: :destroy
has_many :feedbacks
belongs_to :location, :dependent => :destroy
# Association validations
validates_presence_of :category
validates_presence_of :user
# Attribute validations
validates_presence_of :title, message: "Please add a title."
validates_presence_of :subtitle, message: "Please add a subtitle."
validates_presence_of :price, message: "Please add a price."
validates_presence_of :title, message: "Please select a condition."
require 'rails_helper'
RSpec.describe Listing, type: :model do
#Associations
it { should belong_to(:user) }
it { should belong_to(:category) }
it { should have_many(:photos) }
it { should have_many(:watches) }
it { should have_many(:watchers).through(:watches) }
it { should have_many(:offers) }
it { should belong_to(:location).dependent(:destroy) }
#Association validations
it { should validate_presence_of(:category) }
it { should validate_presence_of(:user) }
#Attribute validations
it { should validate_presence_of(:title).with_message("Please add a title.") }
it { should validate_presence_of(:subtitle).with_message("Please add a subtitle.") }
it { should validate_presence_of(:price).with_message("Please add a price.") }
it { should validate_presence_of(:title).with_message("Please select a condition.") }
注意使用 RSpec.describe Class, type: :model
指定测试类型。
我会阅读 Shoulda 自述文件,其中详细解释了各种示例组中匹配器的可用性。他们提供四类匹配器:
ActiveRecord and ActiveModel matchers are available only in model
example groups, i.e., those tagged with type: :model or in files
located under spec/models.
ActionController matchers are available only in controller example
groups, i.e., those tagged with type: :controller or in files located
under spec/controllers.
The route matcher is available also in routing example groups, i.e.,
those tagged with type: :routing or in files located under
spec/routing.
Independent matchers are available in all example groups.
在安排您的规格方面旨在镜像您的应用程序目录(或多或少)。
所以如果你有:
app/models/user.rb
app/services/
app/controllers/
app/presenters/
您可以通过以下方式进行镜像:
spec/models/user_spec.rb
spec/services/
spec/controllers/
spec/presenters/
您可能会有一些额外的规范文件夹,例如:
spec/features/ (a folder for integration/feature specs)
RSpec 文档对此有一些很好的信息。
我以前从未写过自己的测试,我刚刚完成模型关联并迁移它们,所以现在我想测试它们。我已经添加到 gemfile 并在 group :test
下安装了 gem 'shoulda-matchers', '~> 3.0'
,在 group :development, :test
下安装了 gem 'rspec-rails', '~> 3.0'
。将 shoulda-matchers 的配置添加到 spec/rails_helper.rb 中。下一步是什么?测试文件将放入哪个目录?编写 shoulda 匹配器的句法规则是什么,与 rspec 相同?例如,我如何检查该关联是否正常工作?
class Artist < ApplicationRecord
has_many events, :through => :lineups
end
像这样?
describe Artist do
it { should have_many(:events).through(:lineups) }
end
我觉得不错 - 这是另一个使用 class Listing
测试关联和验证的示例。
class Listing < ActiveRecord::Base
#Associations
belongs_to :user
belongs_to :category, inverse_of: :listings
has_many :photos, dependent: :destroy
has_many :watches
has_many :watchers, -> { uniq }, :through => :watches
has_many :offers, dependent: :destroy
has_many :feedbacks
belongs_to :location, :dependent => :destroy
# Association validations
validates_presence_of :category
validates_presence_of :user
# Attribute validations
validates_presence_of :title, message: "Please add a title."
validates_presence_of :subtitle, message: "Please add a subtitle."
validates_presence_of :price, message: "Please add a price."
validates_presence_of :title, message: "Please select a condition."
require 'rails_helper'
RSpec.describe Listing, type: :model do
#Associations
it { should belong_to(:user) }
it { should belong_to(:category) }
it { should have_many(:photos) }
it { should have_many(:watches) }
it { should have_many(:watchers).through(:watches) }
it { should have_many(:offers) }
it { should belong_to(:location).dependent(:destroy) }
#Association validations
it { should validate_presence_of(:category) }
it { should validate_presence_of(:user) }
#Attribute validations
it { should validate_presence_of(:title).with_message("Please add a title.") }
it { should validate_presence_of(:subtitle).with_message("Please add a subtitle.") }
it { should validate_presence_of(:price).with_message("Please add a price.") }
it { should validate_presence_of(:title).with_message("Please select a condition.") }
注意使用 RSpec.describe Class, type: :model
指定测试类型。
我会阅读 Shoulda 自述文件,其中详细解释了各种示例组中匹配器的可用性。他们提供四类匹配器:
ActiveRecord and ActiveModel matchers are available only in model example groups, i.e., those tagged with type: :model or in files located under spec/models.
ActionController matchers are available only in controller example groups, i.e., those tagged with type: :controller or in files located under spec/controllers.
The route matcher is available also in routing example groups, i.e., those tagged with type: :routing or in files located under spec/routing.
Independent matchers are available in all example groups.
在安排您的规格方面旨在镜像您的应用程序目录(或多或少)。
所以如果你有:
app/models/user.rb
app/services/
app/controllers/
app/presenters/
您可以通过以下方式进行镜像:
spec/models/user_spec.rb
spec/services/
spec/controllers/
spec/presenters/
您可能会有一些额外的规范文件夹,例如:
spec/features/ (a folder for integration/feature specs)
RSpec 文档对此有一些很好的信息。