如何在 Rails 中测试关注点 [英] How to Test a Concern in Rails
问题描述
鉴于我在具有 full_name
方法的 Rails 4 应用程序中有一个 Personable
问题,我将如何使用 RSpec 进行测试?
Given that I have a Personable
concern in my Rails 4 application which has a full_name
method, how would I go about testing this using RSpec?
关注点/personable.rb
module Personable
extend ActiveSupport::Concern
def full_name
"#{first_name} #{last_name}"
end
end
推荐答案
你发现的方法肯定可以测试一些功能,但看起来很脆弱——你的虚拟类(实际上只是一个 Struct
在您的解决方案中)可能会或可能不会表现得像一个真正的类,include
是您所关心的.此外,如果您尝试测试模型问题,除非您相应地设置数据库,否则您将无法执行诸如测试对象的有效性或调用 ActiveRecord 回调之类的操作(因为您的虚拟类将没有数据库表支持它).此外,您不仅要测试关注点,还要在模型规范中测试关注点的行为.
The method you found will certainly work to test a little bit of functionality but seems pretty fragile—your dummy class (actually just a Struct
in your solution) may or may not behave like a real class that include
s your concern. Additionally if you're trying to test model concerns, you won't be able to do things like test the validity of objects or invoke ActiveRecord callbacks unless you set up the database accordingly (because your dummy class won't have a database table backing it). Moreover, you'll want to not only test the concern but also test the concern's behavior inside your model specs.
那为什么不用一颗石头杀死两只鸟呢?通过使用 RSpec 的 共享示例组,您可以针对使用它们的实际类(例如模型)测试您的关注点并且您将能够在使用它们的任何地方测试它们.而且您只需编写一次测试,然后将它们包含在任何使用您关注的模型规范中.在您的情况下,这可能如下所示:
So why not kill two birds with one stone? By using RSpec's shared example groups, you can test your concerns against the actual classes that use them (e.g., models) and you'll be able to test them everywhere they're used. And you only have to write the tests once and then just include them in any model spec that uses your concern. In your case, this might look something like this:
# 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 = FactoryBot.build(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
当你开始做你关心的事情时,这种方法的优势变得更加明显,比如调用 AR 回调,除了 AR 对象之外的任何事情都不会做.
The advantages of this approach become even more obvious when you start doing things in your concern like invoking AR callbacks, where anything less than an AR object just won't do.
这篇关于如何在 Rails 中测试关注点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!