如何在Rails中testing关注
鉴于我有我的Rails 4应用程序有一个full_name
方法Personable
关心,我将如何去使用RSpec进行testing?
关注/ personable.rb
module Personable extend ActiveSupport::Concern def full_name "#{first_name} #{last_name}" end end
你发现的方法肯定会testing一些function,但看起来非常脆弱 – 你的虚拟类(实际上只是你的解决scheme中的一个Struct
)可能会或可能不会像真正的类一样include
你的关注。 另外,如果您试图testing模型问题,您将无法执行诸如testing对象的有效性或调用ActiveRecordcallback的事情,除非相应地设置数据库(因为您的虚拟类不会有数据库表的后备它)。 此外,您不仅要testing关注点,还要testing模型规范中关注的行为。
那么为什么不一箭双雕? 通过使用RSpec的共享示例组 ,您可以针对使用它们的实际类(例如模型)来testing您的担忧, 并且可以在使用它们的任何地方testing它们。 你只需要写一次testing,然后把它们包含在任何使用你的关注的模型规范中。 在你的情况下,这可能看起来像这样:
# app/models/concerns/personable.rb module Personable extend ActiveSupport::Concern def full_name "#{first_name} #{last_name}" end end # spec/concerns/personable_spec.rb require 'spec_helper' shared_examples_for "personable" do let(:model) { described_class } # the class that includes the concern it "has a full name" do person = FactoryGirl.create(model.to_s.underscore.to_sym, first_name: "Stewart", last_name: "Home") expect(person.full_name).to eq("Stewart Home") end end # spec/models/master_spec.rb require 'spec_helper' require Rails.root.join "spec/concerns/personable_spec.rb" describe Master do it_behaves_like "personable" end # spec/models/apprentice_spec.rb require 'spec_helper' describe Apprentice do it_behaves_like "personable" end
这种方法的好处就更加明显了,当你开始在你关心的事情上做一些事情时,比如调用ARcallback函数,任何小于AR对象的东西都不会做。
回应我收到的意见,这是我最终做的(如果有人有改进,请随时张贴) :
规格/关注/ personable_spec.rb
require 'spec_helper' describe Personable do let (:test_class) { Struct.new(:first_name, :last_name) { include Personable } } let (:personable) { test_class.new("Stewart", "Home") } it "has a full_name" do personable.full_name.should == "#{personable.first_name} #{personable.last_name}" end end
另一个想法是使用with_model gem来testing这样的事情。 我正在考虑自己testing一个问题,并看到pg_search gem这样做 。 看起来好于在个别模型上testing,因为这些可能会改变,而且在规范中定义你需要的东西是很好的。