Changes to RSpec Error checking - ruby

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

Related

How to raise standard error from a rspec test?

So I have an rspec test that I am trying to get my program to validate against:
code snippet from rspec test:
context '#validate(test_tool)' do
it { expect(test_tool.validate).to raise_error StandardError }
code snippet from test_tool (test_tool is the program I wrote to pass the rspec test) Inside test_tool there are multiple methods, but I just pulled out the one method that the rspec test is looking for:
def self.validate
raise StandardError
end
I have googled everywhere. No matter how I attempt to raise this error. I keep getting an error. Please see snippet of console output:
example at ./spec/training_site/spec_test.rb:56 (FAILED - 1)
Failures:
1) MyClass #validate(test_tool)
Failure/Error: it { expect(MyClass.validate).to raise_error StandardError }
StandardError:
StandardError
Line 56 is just the 2nd line from the 1st code snippet.
Basically, I'm looking for troubleshooting and or example on how I should accomplish this.
This is correct spec. You should use {} (block brackets) since you are waiting for it to raise error. Simple brackets that you have use are for values checking.
context '#validate(test_tool)' do
it { expect{test_tool.validate}.to raise_error StandardError }

Ruby Koans class or module required

I am getting the following error in Ruby Koans:
AboutHashes#test_accessing_hashes_with_fetch has damaged your karma.
The Master says:
You have not yet reached enlightenment.
I sense frustration. Do not be afraid to ask for help.
The answers you seek...
class or module required
Please meditate on the following code:
/home/s/Downloads/github/rubykoans/about_hashes.rb:26:in `test_accessing_hashes_with_fetch'
The line in question is part of the following method:
def test_accessing_hashes_with_fetch
hash = { :one => "uno" }
assert_equal "uno", hash.fetch(:one)
assert_raise(nil) do
hash.fetch(:doesnt_exist)
end
As you can see, it is asking for a class or module, so I am confused as this is not an error I've encountered before in the Koans.
The problem is on these lines:
assert_raise(nil) do
hash.fetch(:doesnt_exist)
end
The assert_raise test macro expects as its argument a class of Exception. You provided nil.
To skip to the answer, calling fetch on a hash with a key that doesn't exist in the hash will raise a KeyError Exception. So the test should have this:
assert_raise(KeyError) do
hash.fetch(:doesnt_exist)
end

rspec: raise_error usage to match error message

I raised an error using raise(ConfigurationError.new(msg))
I tried to test this with rspec:
expect {
Base.configuration.username
}.to raise_error(ConfigurationError, message)
But this doesn't work. How can I test this? The goal is to match message.
You can match error message with regex:
it { expect{ Foo.bar }.to raise_error(NoMethodError, /private/) }
This will check if NoMethodError raised with private method message not undefined method.
Will be useful because NoMethodError.new didn't pass tests even with same error message.
Make sure you are using rspec > 2.14.0 and take a look at this commit:
https://github.com/rspec/rspec-expectations/commit/7f02b503d5ae48d1141b6465acd0a7a4e1bb84dd
it "passes if an error instance is expected" do
s = StandardError.new
expect {raise s}.to raise_error(s)
end
An alternative solution is to use a block where you assert on various properties of |error|. Using the names in the original question:
expect { Base.configuration.username }
.to(raise_error do |error|
expect(error).to be_a(ConfigurationError)
expect(error.message).to eq 'My configuration message'
end)

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

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.

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

Resources