如何在 Rails 中测试关注点 [英] How to Test a Concern in Rails

查看:43
本文介绍了如何在 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 includes 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆