mardi 24 mai 2016

Rspec Test Haml Template Output in Object Presenter

I am trying to figure out class/method/instantiation process I should use in Rspec to get a functioning view template that includes both the standard ActionView herlper methods and HAML helper methods.

I have implemented presenters in my rails app as is done in RailsCast #287

I have a presenter where I want to do some output that uses one of the HAML helpers.

Here is the base presenter:

class BasePresenter
  attr_reader :object, :template

  def initialize(object, template)
    @object = object
    @template = template
  end
end

Here is an example of a theoretical presentable object and it's presenter class:

class FakeObject
  def a_number
    rand(10).to_s
  end
end

class FakePresenter < BasePresenter
  def output_stuff
    # #content_tag is standard ActionView
    template.content_tag(:span) do
      # #succeed is from the haml gem
      template.succeed('.') do
        object.a_number
      end
    end          
  end
end

If I were to write a test for this in Rspec and only the #content_tag method were being used, this would work, as it's part of ActionView. However, #succeed is from the haml gem and isn't available with my current test.

Test:

require 'rails_helper'

describe FakeObjectPresenter do

  let(:template){ ActionView::Base.new }
  let(:obj){ FakeObject.new }
  let(:presenter){ FakeObjectPresenterPresenter.new obj, template }

  describe '#output_stuff' do
    it{ expect(presenter.output_stuff).to match(/<span>\d+<\/span>/) }
  end
end

Failures:

  1) FakeObjectPresenter #output_stuff 
     Failure/Error:
       template.succeed('.') do
         object.a_number

     NoMethodError:
       undefined method `succeed' for #<ActionView::Base:0x00560e818125a0>

What class should I be instantiating as my template instead of ActionView::Base.new to get the haml methods available in the test?

If you'd like to easily play around with this, you can dump the below code into a spec.rb file in a rails app and run it as a demo:

require 'rails_helper'

# Define classes to be tested
class FakeObject
  def a_number
    rand(10).to_s
  end
end

class BasePresenter
  attr_reader :object, :template

  def initialize(object, template)
    @object = object
    @template = template
  end
end

class FakeObjectPresenter < BasePresenter
  def output_stuff
    # #content_tag is standard ActionView
    template.content_tag(:span) do
      # #succeed is from the haml gem
      template.succeed('.') do
        object.a_number
      end
    end          
  end
end

# Actual spec
describe FakeObjectPresenter do

  let(:template){ ActionView::Base.new }
  let(:obj){ FakeObject.new }
  let(:presenter){ FakeObjectPresenter.new obj, template }

  describe '#output_stuff' do
    it{ expect(presenter.output_stuff).to match(/<span>\d+<\/span>/) }
  end
end

Aucun commentaire:

Enregistrer un commentaire