在Padrino(Sinatra)与RSpec一起测试助手

时间:2014-03-05 17:59:58

标签: ruby rspec sinatra padrino

我正在尝试在Padrino(Sinatra)应用程序中测试助手。我的帮助方法本身就是调用Padrino核心辅助方法,但它们是未定义的。该错误仅出现在RSpec中,而应用程序正常。所以我在RSpec中包含我的助手的方式使它松散“Padrino scope”但我不知道如何在我的RSpec环境中正确地使用Padrino助手的范围。

我的助手:

module AdminHelper
  Sort = Struct.new(:column, :order)

  def sort_link(model, column)
    order = sorted_by_this?(column) ? 'desc' : 'asc'
    link_to mat(model, column), url(:pages, :index, sort: column, order: order)
  end

  def sorted_by_this?(column)
    column.to_s == @sort.column && @sort.order == 'asc'
  end
end

Lenstroy::Admin.helpers AdminHelper

我的规格:

describe AdminHelper do
  before(:all) do
    class AdminHelperClass
      include AdminHelper
    end
  end
  subject(:helper) { AdminHelperClass.new }

  describe '#sort_link' do
    context "with :pages and :title parameters" do
      before do
        sort = AdminHelperClass::Sort.new('title', 'asc')
        helper.instance_variable_set('@sort', sort)
      end

      subject { helper.sort_link(:pages, :title) }

      it { should match(/<a href=([^ ]+)pages/) }
    end
  end
end

导致错误:

1) AdminHelper#sort_link with :pages and :title parameters 
     Failure/Error: subject { helper.sort_link(:pages, :title) }
     NoMethodError:
       undefined method `mat' for #<AdminHelperClass:0x007f1d951dc4a0>

包含一个定义mat的帮助程序不起作用,因为一个方法依赖于另一个帮助程序而且它会继续...

更新
在我的规范助手中,我有:

def app(app = nil, &blk)
  @app ||= block_given? ? app.instance_eval(&blk) : app
  @app ||= Lenstroy::Admin
  @app.register Padrino::Helpers
  @app.register Padrino::Rendering
  @app
end

在我的规范中我有:

it "returns link to resource with sort parameters" do
  app do
    get '/' do
      sort_link(:pages, :title)
    end
  end
  get "/"
  last_response.body.should =~ /<a href=([^ >]+)pages/
end

现在测试失败,last_response.body''

2 个答案:

答案 0 :(得分:1)

方法#mat在Padrino::Admin::Helpers::ViewHelpers中定义。你可以做到

class AdminHelperClass
  include Padrino::Admin::Helpers::ViewHelpers
  include AdminHelper
end

更新

如果您的方法确实依赖于所有这些路线和帮助,您应该考虑对您的应用进行完整的模拟,如下所示:

def mock_app(base=Padrino::Application, &block)
  @app = Sinatra.new(base, &block)
  @app.register Padrino::Helpers
  @app.register Padrino::Rendering
  # register other things
end

def app
  Rack::Lint.new(@app)
end

mock_app do
  get '/' do
    sort_link(my_model, my_column)
  end
end

get "/"
assert_equal "some test text", body

以下是在padrino-admin中完成的操作:https://github.com/padrino/padrino-framework/blob/master/padrino-admin/test/test_admin_application.rb

答案 1 :(得分:1)

我遇到了同样的问题(并且非常沮丧地追踪模块并包含它们)。到目前为止,我已经完成了我的规范:

1)明确定义我的模块(如how to use padrino helper methods in rspec中所述)

module MyHelper
  ...
end

MyApp::App.helpers MyHelper

2)在规范的顶部自动包含帮助者。 (现在我只有一个帮助规范,但将来我可能会尝试将其移动到spec_helper.rb。)

describe MyHelper do
  let(:helpers) { Class.new }
  before { MyApp::App.included_modules.each { |m| helpers.extend m } }
  subject { helpers }

  it 'blah' do
    expect(subject.helper_method).to eq 'foo'
  end
end