Why are helper methods not working in view specs?
Solution 1:
View specs usually does not need to call the real helper (if you wan't to test the helper then you can do a helper spec).
It's faster and easier to just stub the helper method to return the value you want for your given test:
context 'with a logged user' do
before(:each) do
allow(view).to receive(:logged_in?).and_return(true)
end
it 'has a logout link' do
render
expect(rendered).to have_link 'Logout'
end
end
context 'with no logged user' do
before(:each) do
allow(view).to receive(:logged_in?).and_return(false)
end
it 'has a login link' do
render
expect(rendered).to have_link 'Login'
end
end
When you do model, controller, views, helper or any other isolated test, it does not have access to all the app since it's designed to run fast. For example: controller tests does not render views by default, model specs only tests the model, view specs do not have a context of the request nor session, etc.
You can have full real user tests using integration (feature) specs which runs the whole user interaction from beginning to end with access to everything, even controlling what the user clicks.
Solution 2:
Update to the accepted answer, it now seems necessary to use without_partial_double_verification
to get around the ActionView::Base does not implement: field_name
error.
Example code:
let(:logged_in) { true }
before(:each) do
without_partial_double_verification do
allow(view).to receive(:logged_in?).and_return(logged_in)
end
render
end
it 'has a logout link' do
expect(rendered).to have_link 'Logout'
end
context 'with no logged user' do
let(:logged_in) { false }
it 'has a login link' do
expect(rendered).to have_link 'Login'
end
end