RSpec2 & Rails3, issue with the basics of testing helpers - ruby-on-rails

That's certainly trivial but can't figure out what goes wrong.
Helper : app/helpers/bookings_helper.rb
module BookingsHelper
def booking_price(booking)
"something"
end
end
Helper spec : spec/helpers/bookings_helper_spec.rb
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe BookingsHelper do
describe "#booking_price" do
helper.booking_price.should == 'something'
end
end
Error
/Library/Ruby/Gems/1.8/gems/activesupport-3.0.4/lib/active_support/whiny_nil.rb:48:in `method_missing': undefined method `booking_price' for nil:NilClass (NoMethodError)

Try using it instead of describe for the inside block:
describe BookingsHelper do
it "#booking_price" do
helper.booking_price.should == 'something'
end
end

Related

Rails: Moving a helper method form a test to test_helper.rb

I am trying to move a helper method from a controller test to the test_helper.rb:
# example_controller_test.rb
require 'test_helper'
class ExampleControllerTest < ActionController::TestCase
should 'get index' do
turn_off_authorization
get :show
assert_response :success
end
end
# test_helper.rb
class ActionController::TestCase
def turn_off_authorization
ApplicationController.any_instance
.expects(:authorize_action!)
.returns(true)
end
end
However, I'm getting an error:
NameError: undefined local variable or method `turn_off_authorization' for #<ExampleControllerTest:0x000000067d6080>
What am I doing wrong?
Turns out that I had to wrap the helper method into a module:
# test_helper.rb
class ActionController::TestCase
module CheatWithAuth do
def turn_off_authorization
# some code goes here
end
end
include CheatWithAuth
end
I still don't know why the original version didn't work.
The idea came from another answer:
How do I write a helper for an integration test in Rails?
Edit: Another solution just came from my friend:
# test_helper.rb
class ActiveSupport::TestCase
def turn_off_authorization
# some code goes here
end
end
Note that ActiveSupport::TestCase (not ActionController::TestCase) is being used here.

Testing Rails helper with Rspec: undefined local variable or method `request'

I have a helper method that uses 'request' to determine the URL. However, rspec can't seem to find request. I thought request was available to all front-facing tests?
How can I account for the request method in my spec?
Helper Spec
require 'spec_helper'
describe ApplicationHelper do
describe "full_title" do
it "should include the page title" do
expect(full_title("help")).to include('help')
end
end
end
Helper methods
def full_title(page_title)
if staging? # causing the issue
base_title = "Staging"
else
base_title = "Company Name"
end
if page_title.empty?
"#{base_title} | Tag line "
else
"#{base_title} | #{page_title} "
end
end
def staging? # the request here seems to be the problem
request.original_url.include? "staging"
end
Rspec error
Failure/Error: expect(full_title("help")).to include('help')
NameError:
undefined local variable or method `request' for #<RSpec::ExampleGroups::ApplicationHelper_2::FullTitle:0x00000106260078>
Thanks in advance.
First off: request is only available in the controller tests (and even then only in the request specs I think), helper tests are really basic and isolated. Which is good. Your helper code should be really minimal and normally only work on the input it receives.
However this is pretty easily solvable by using stubbing.
So write something like
#note, OP needed to replace 'helper' with 'self'for Rails 4.0.0 and Rspec 3.0
require 'rails_helper'
describe ApplicationHelper do
describe "full_title" do
context "in staging" do
it "should include the page title" do
helper.should_receive(:staging?).and_return(true)
expect(full_title("help")).to include('help')
end
end
context "not in staging" do
it "should include the page title" do
helper.should_receive(:staging?).and_return(false)
expect(full_title("help")).to include('help')
end
end
end
end
Which is imho a very clear, and then you write separate tests for your staging? method:
describe "staging?" do
context "when in staging" do
it "returns true" do
helper.stub(:request) { OpenStruct.new(original_url: 'staging') }
expect( helper.staging? ).to be true
end
end
context "when not in staging" do
it "returns false" do
helper.stub(:request) { OpenStruct.new(original_url: 'development') }
expect(helper.staging?).to be false
end
end
end
end
Some small remarks: ruby default indentation is 2 spaces.
Secondly, your function now literally says return true if true, ideally it should be written like
def staging?
request.original_url.include? "staging"
end

How to test content_for using rspec

I"m attempting to test my application_helper's yield_for method but I don't know the best way to go about it. I've tried the code below but get the following error:
Failure/Error: self.stub(:content_for).with(:foo).and_return('bar')
Stub :content_for received unexpected message :with with (:foo)
application_helper.rb
def yield_for(content_sym, default = '')
content_for?(:content_sym) ? content_for(content_sym) : default
end
application_helper_spec.rb
describe '#yield_for' do
it 'should fetch the yield' do
self.stub(:content_for).with(:foo).and_return('bar')
helper.yield_for(:foo).should == 'bar'
end
end
I'm using rspec (3.1.0) and it should work with:
describe '#yield_for' do
it 'should fetch the yield' do
helper.content_for(:foo, 'bar')
expect(helper.yield_for(:foo)).to eq('bar')
end
end
Try making the stub on the helper
it 'should fetch the yield' do
helper.stub(:content_for).with(:foo).and_return('bar')
helper.yield_for(:foo).should == 'bar'
end
Got your test passing with this
def yield_for(content_sym, default = '')
content_for(content_sym) ? content_for(content_sym) : default
end

RSpec - How to create helper method available to tests that will automatically embed "it" tests

I am new to ruby/rails/rspec etc.
Using rspec 2.13.1, I want to create a module with a method that can be called from my tests resulting to subsequent calls of the "it" method of the RSpec::Core::ExampleGroup.
My module:
require 'spec_helper'
module TestHelper
def invalid_without(symbols)
symbols = symbols.is_a?(Array) ? symbols : [symbols]
symbols.each do |symbol|
it "should not be valid without #{symbol.to_s.humanize}" do
# Gonna nullify the subject's 'symbol' attribute here
# and expect to have error on it
end
end
end
end
The code above was added to:
spec/support/test_helper.rb
and in my spec_helper.rb, in the RSpec.configure block, I added the following:
config.include TestHelper
Now, in a test, I do the following:
describe Foo
context "when invalid" do
invalid_without [:name, :surname]
end
end
Running this, I get:
undefined method `invalid_without' for #<Class:0x007fdaf1821030> (NoMethodError)
Any help appreciated..
Use shared example group.
shared_examples_for "a valid array" do |symbols|
symbols = symbols.is_a?(Array) ? symbols : [symbols]
symbols.each do |symbol|
it "should not be valid without #{symbol.to_s.humanize}" do
# Gonna nullify the subject's 'symbol' attribute here
# and expect to have error on it
end
end
end
describe Foo do
it_should_behave_like "a valid array", [:name, :surname]
end

Net.tutorialplus.com -Rspec tutorial- NoMethodError

I am following Rspec testing tutorial on Net.Tutsplus.com.
I've found problem I couldn't solve. Here the thing.
When I run test:
C:\projekt>rspec spec/library_spec.rb --format nested
I get:
C:/projekt/spec/library_spec.rb:35:in `block (3 levels) in <top (required)>': un
defined method `books' for nil:NilClass (NoMethodError)
library_spec.rb looks like that:
require "spec_helper"
describe "Library Object" do
before :all do
lib_arr = [
Book.new("JavaScript: The Good Parts", "Douglas Crockford", :development),
Book.new("Designing with Web Standarts", "Jeffrey Zeldman", :design),
Book.new("Don't Make me Think", "Steve Krug", :usability),
Book.new("JavaScript Patterns", "Stoyan Sefanov", :development),
Book.new("Responsive Web Design", "Ethan Marcotte", :design)
]
File.open "books.yml", "w" do |f|
f.write YAML::dump lib_arr
end
end
before :each do
#lib = Library.new "books.yml"
end
describe "#new" do
context "with no parameters" do
it "has no books" do
lib = Library.new
lib.books.length.should == 0
end
end
context "with a yaml file name parameters " do
it "has five books"
#lib.books.length.should == 5
end
end
end
Due to tutorial instructions I changed library.rb to:
require 'yaml'
class Library
attr_accessor :books
def initalize lib_file = false
#lib_file = lib_file
#books = #lib_file ? YAML::load(File.read(#lib_file)) : []
end
end
According to tutorial it should solve "books-NoMethodError" problem but it still apper.
Where is the problem?
Thanks for help!
undefined method books for nil:NilClass (NoMethodError) just means that you are calling a method books on something that is nil, in this case #lib.
You need to place the before(:each) hook that defines #lib inside a context or describe block, in your code it is not available in the describe '#new' block.
Also, you were missing a do after defining the it "has five books" spec.
I've corrected these errors below:
describe "#new" do
before :each do
#lib = Library.new "books.yml"
end
context "with no parameters" do
it "has no books" do
lib = Library.new
lib.books.length.should == 0
end
end
context "with a yaml file name parameters " do
it "has five books" do
#lib.books.length.should == 5
end
end
end

Resources