RSpec帮助器规范模拟ActiveRecord

时间:2016-02-26 12:58:47

标签: ruby-on-rails rspec

我使用RSpec进行测试。我经常发现写好帮手规格很难。这是一个例子:

app/helper/time_helper.rb我有以下代码:

# Returns a text field built with given FormBuilder for given attribute                        |  ~                                                                                                    
# (assumed to be a datetime). The field value is a string representation of                    |  ~                                                                                                    
# the datetime with current TimeZone applied.
def datetime_timezone_field(form_builder, attribute)
  date_format = '%Y-%m-%d %H:%M'
  datetime = form_builder.object.send(attribute)
  form_builder.text_field attribute,
                          value: datetime.in_time_zone.strftime(date_format)
end

测试时,我需要将FormBuilder传递给方法。我知道如何创建TestView,但如何创建下面使用的TestModel?在我的spec文件(spec / helpers / time_helper_spec.rb)中,我有类似的东西:

describe '#datetime_timezone_field' do
  class TestView < ActionView::Base; end

  let(:form_builder) do
    ActionView::Helpers::FormBuilder.new(TestModel.model_name.singular,
                                         TestModel.new,
                                         TestView.new,
                                         {})
  end

  it # Some tests here to check the output...
end

我的问题是TestModel。我如何模拟这样的对象?此助手未连接到我的应用程序中的模型。 TestModel应该是&#34;任何模型类&#34;在我的应用程序中或者是否有更好的方法来编写辅助方法来摆脱这个问题?

1 个答案:

答案 0 :(得分:1)

你实际上并没有真正测试模型的行为,你只需要一个对象来响应你传入的属性。

我以为你可以做到

class TestModel
  include ActiveModel::Model

  attr_accessor :whatever_attribute
end

您可能不需要全部ActiveModel,但我不知道表单构建器希望它具有哪些部分。你总能看到这些。

所以基本上你会做

let(:form_builder) do
    ActionView::Helpers::FormBuilder.new(TestModel.model_name.singular,
                                         TestModel.new(whatever_attribute: Time.zone.now),
                                         TestView.new,
                                         {})
end

我没有对此进行过测试,但我认为没有任何理由不应该这样做。