如何测试Rails中的关注点

时间:2013-05-13 15:01:20

标签: ruby-on-rails testing rspec

鉴于我的Rails 4应用程序中有一个Personable问题,它有一个full_name方法,我将如何使用RSpec进行测试?

顾虑/ personable.rb

module Personable
  extend ActiveSupport::Concern

  def full_name
    "#{first_name} #{last_name}"
  end
end

5 个答案:

答案 0 :(得分:154)

您找到的方法肯定会测试一些功能,但看起来非常脆弱 - 您的虚拟类(实际上只是解决方案中的Struct)可能会或可能不会像真正的类{{{ 1}}你的担忧。此外,如果您尝试测试模型问题,除非您相应地设置数据库,否则您将无法测试对象的有效性或调用ActiveRecord回调(因为您的虚拟类将没有数据库表支持)它)。此外,您不仅要测试关注点,还要测试模型规范中关注点的行为。

那么为什么不一石二鸟?通过使用RSpec的shared example groups,您可以根据使用它们的实际类(例如,模型)测试您的关注点,您将能够在它们使用的任何地方测试它们。而且您只需编写一次测试,然后将它们包含在任何使用您关注的模型规范中。在您的情况下,这可能看起来像这样:

include

当您开始处理关注事项时,这种方法的优势变得更加明显,比如调用AR回调,其中任何比AR对象更少的东西都不会。

答案 1 :(得分:51)

回应我收到的评论,这是我最终做的事情(如果有人有改进,请随时发布)

<强>规格/关切/ 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
    expect(personable.full_name).to eq("#{personable.first_name} #{personable.last_name}")
  end
end

答案 2 :(得分:5)

另一个想法是使用with_model gem来测试这样的事情。我本人希望自己测试一个问题并看到pg_search gem doing this。它似乎比在单个模型上测试要好得多,因为它们可能会发生变化,并且很好地定义了您的规范中需要的东西。

答案 3 :(得分:0)

以下对我有用。就我而言,我担心的是调用生成的 *_path 方法,而其他方法似乎不起作用。通过这种方法,您可以访问一些仅在控制器上下文中可用的方法。

担忧:

module MyConcern
  extend ActiveSupport::Concern

  def foo
    ...
  end
end

规格:

require 'rails_helper'

class MyConcernFakeController < ApplicationController
  include MyConcernFakeController
end

RSpec.describe MyConcernFakeController, type: :controller do    
  context 'foo' do
    it '' do
      expect(subject.foo).to eq(...)
    end
  end
end

答案 4 :(得分:-1)

只需在规范中包括您所关注的问题,并测试它是否返回正确的值即可。

RSpec.describe Personable do
  include Personable

  context 'test' do
    let!(:person) { create(:person) }

    it 'should match' do
       expect(person.full_name).to eql 'David King'
    end
  end
end
相关问题