trailblazer / cells

View components for Ruby and Rails.
https://trailblazer.to/2.1/docs/cells.html
3.07k stars 236 forks source link

Question: How to mock (or expect) message calls for helpers in cells? #264

Closed berkes closed 9 years ago

berkes commented 9 years ago

In rails view tests with rspec, one can do:

allow(view).to receive(:current_actor).and_return double(:current_actor, user: @user)
expect(view).to receive(:icon).with('user', :dark)
render

In order to stub out "external" helpers. It also allows setting expecations on such helpers to see that the view calls them correctly. This is especially helpfull for helpers that have a complex state.

I a cell, I don't know what to set such expectations on. Is this even possible?

I've submitted this to stackoverflow too.

apotonick commented 9 years ago

Can you give me some more details on those "external helpers"? Is that to test if methods are called properly? Theoretically, you can do that as follows.

cell = cell(:song, song)
expect(cell).to_receive ..
cell.(:show)

Remember, every helper is just an instance method call on the cell instance. Does that help?

berkes commented 9 years ago

I should have mentioned this is cells3 with a "controller" type cell:

app/cells/analysis_cell.rb

def chart(params)
  @analysis_chart = params[:analysis_chart]
  render
end

app/cells/analysis/chart.html.slim (I've extensively tested with erb too, slim or ERB hardly seems to matter for this question)

= indicator_chart_tag(@analysis_chart.charts)

spec/cells/analysis_cell_spec.rb

describe 'rendering a chart' do
  let(:chart) { double(:chart) }
  let(:analysis_chart) { double(:analysis_graph, charts: [chart]) }

  it 'renders a chart using the indicator_chart_tag helper' do
    expect(view).to receive(:indicator_chart_tag).with([chart])
    render_cell(:analysis, :chart, analysis_chart: analysis_chart)
  end
end

Here's what I tried, already (from memory):

describe AnalysisCell, type: :cell do
   include ActionView::TestCase::Behavior
   #..
     expect(_view).to receive(:indicator_chart_tag)
     expect_any_istance_of(AnalysisCell).to receive(:indicator_chart_tag)
     expect_any_istance_of(ActionView::Basic).to receive(:indicator_chart_tag)

It looks like the way render_cell works, does not allow stubbing at all, but I don't fully understand it, and think (hope) I am overlooking an important piece.

Edit: Yes, since this is a (way too) complex helper, for now, we only want to test that this helper is called with the proper arguments. Not that it renders the correct charts.

apotonick commented 9 years ago

Ah, ok. cells3... Hmm... do this.

cell = cell(:song)
cell.mocking_sucks! # do your mocking here ;)
cell.render_state(:show, song, volume: 9).must_match ...
apotonick commented 9 years ago

Closing this, as this works with rspec-cells 0.3.