undefined method `valid?' for #<Class:0x94b626c> - ruby

Why am getting this error? How to fix?
1) User should exist
Failure/Error: User.should be_valid
NoMethodError:
undefined method `valid?' for #<Class:0x94b626c>
Test is:
require 'spec_helper'
describe User do
it "should exist" do
User.should be_valid
end
it "should not allow me to create a new user without required fields" do
User.new(:email => 'bob').should_not be_valid
end
end
The second test works ok, how can I get the first one to pass? I just want it to check that the model exists

Testing a class implicitly tests that it exists. Both code samples will error out if the class doesn't exist. The first is unnecessary.

Replace User.should be_valid with User.new.should be_valid in the first test. RSpec is calling valid? on the User class instead of an instance of it.

Related

NoMethodError: undefined method `stub!' for nil:NilClass

I'm trying to put the rspec for active link condition present in the application_helper.rb.
Application_helper.rb code:
def active_class(link_path)
current_page?(link_path) ? 'active' : ''
end
i tried to put the rspec for this active_class method, i used stub for this purpose.This is my rspec code for active_class method.
Application_helper_spec.rb code:
describe 'when called from "index" action' do
before
helper.stub!(:action_name).and_return('index')
end
it 'should do' do
helper.active_class.should == 'active'
end
describe 'when called from "other" action' do
before
helper.stub!(:action_name).and_return('other')
end
it 'should do' do
helper.active_class.should == 'empty'
end
I'm getting the error as undefined method stub.How can i get overcome from this issue?
I use slightly different interface for stubbing and mocking which looks like this:
allow(helper).to receive(:action_name).and_return('index')
When you just want to stub the response.
But if you need to set up an expectation:
expect(helper).to receive(:action_name).and_return('index')
You can find more info in the docs: https://relishapp.com/rspec/rspec-mocks/v/3-7/docs/basics

Ruby basic RSpec test does not pass

I'm not able to understand why the following Rspec test does not pass -
require "rspec"
require_relative "file-to-be-tested"
describe Customer do
it "is valid with firstname" do
customer = Customer.new("handy")
expect(customer).to be_valid
end
end
for the corresponding Class definition -
class Customer
attr_reader :firstname
def initialize(firstname)
#firstname = firstname
end
end
these two code snippets are in separate files in the same folder, so when i run ~rspec <first-filename> in the terminal, I get the following error -
F
Failures:
1) Customer is valid with firstname
Failure/Error: expect(customer).to be_valid
expected #<Customer:0x007f90e50f3110> to respond to `valid?`
# ./poodr/poodr_rspec.rb:8:in `block (2 levels) in <top (required)>'
Finished in 0.00551 seconds (files took 0.52876 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./poodr/poodr_rspec.rb:6 # Customer is valid with firstname
be_valid is an rspec-rails method, but it looks like you're using just straight rspec. you could do something like:
require "rspec"
require_relative "file-to-be-tested"
describe Customer do
it "is valid with firstname" do
expect { Customer.new('handy') }.to_not raise_error
end
end
What are you expecting the to be_valid test to do? The issue is that the Customer class has no method called valid? which your test is trying to test.
A hack to move your test along if your doing test driven development:
class Customer
def valid?
true
end
end
You now have a method called valid and your test will pass. Obviously it shouldn't always be true so your next step would be to expand the definition of valid?. What check needs to be done to know if a customer is valid or not?

Does should_receive do something I don't expect?

Consider the following two trivial models:
class Iq
def score
#Some Irrelevant Code
end
end
class Person
def iq_score
Iq.new(self).score #error here
end
end
And the following Rspec test:
describe "#iq_score" do
let(:person) { Person.new }
it "creates an instance of Iq with the person" do
Iq.should_receive(:new).with(person)
Iq.any_instance.stub(:score).and_return(100.0)
person.iq_score
end
end
When I run this test (or, rather, an analogous one), it appears the stub has not worked:
Failure/Error: person.iq_score
NoMethodError:
undefined method `iq_score' for nil:NilClass
The failure, as you might guess, is on the line marked "error here" above. When the should_receive line is commented out, this error disappears. What's going on?
Since RSpec has extended stubber functionality, now following way is correct:
Iq.should_receive(:new).with(person).and_call_original
It will (1) check expectation (2) return control to original function, not just return nil.
You're stubbing away the initializer:
Iq.should_receive(:new).with(person)
returns nil, so Iq.new is nil. To fix, just do this:
Iq.should_receive(:new).with(person).and_return(mock('iq', :iq_score => 34))
person.iq_score.should == 34 // assert it is really the mock you get

Changes to RSpec Error checking

I am trying to follow a tutorial on TDD with RSpec that contains the following line:
it 'must have a first_name' do
p = Person.new
p.should_not be_valid
p.errors.on(:first_name).should_not be_nil
end
However I receive the following message in my test:
undefined method `on' for #ActiveModel::Errors:0x007fde0c3eceb0>
What is the correct way to write the code above.
The correct function is errors_on. So that line should be
p.errors_on(:first_name).should_not be_nil

rspec expect throws "undefined method"

I am a complete Ruby newby and am playing around with rspec
I am testing a class (Account) that has this line:
attr_reader :balance
When I try to test it with this method:
it "should deposit twice" do
#acc.deposit(75)
expect {
#acc.deposit(50)
}.to change(Account.balance).to(125)
end
I get this error:
NoMethodError in 'Account should deposit twice'
undefined method `balance' for Account:Class
I don't understand why I get the error since the attribute 'balance' exists, however I can see that it is not a method, but shouldn't rspec be able to find it anyway?
Update:
As Jason noted I should be #acc.balance, since this is what I am asserting. But I get 'nil is not a symbol' when doing this.
It should be #acc.balance
it "should deposit twice" do
#acc = Account.new
#acc.deposit(75)
#acc.balance.should == 75
expect {
#acc.deposit(50)
}.to change(#acc, :balance).to(125)
end
i think it should be
expect {#acc.deposit(50)}.to change(#acc.balance}.to(125)
It should be:
it "should deposit twice" do
#acc.deposit(75)
expect {
#acc.deposit(50)
}.to change { #acc.balance }.to(125)
end
Please note that you need use curly braces { ... } instead of parentheses ( ... ) around #acc.balance. Otherwise #acc.balance is evaluated before it is passed to change method which expects either symbol or block.

Resources