it 'should be an array and not be empty' do
pending
expect(a.class).to be(Array)
expect(a.empty?).to be(false)
expect(a.first.class).to be(ExampleClass)
end
When I run rspec:
Failures:
1) should be an array and not be empty FIXED
Expected pending 'No reason given' to fail. No Error was raised.
# ./spec/example_spec.rb:19
Any ideas why this is being listed as a failure?
As of Rspec 3.x, pending specs are actually run, and if they pass, it's considered a failure (because if it passes, then Rspec thinks it shouldn't be pending).
You can use skip instead of pending to make sure your spec doesn't actually run.
More info: https://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#changes-to-pending-semantics-and-introduction-of-skip
Here's your clue:
should be an array and not be empty FIXED
Things that pass will cause a pending test to fail. Check the docs for examples [1], [2].
RSpec 2
RSpec 3
Related
I'm trying to mock Date.today.wday in a rake task in rspec.
Gem versions: RSpec 2.14.8 --- Rails 4.1.1 --- ruby 2.0.0
Here is a simplified fake version of my test to illustrate essentially what I'm trying to do:
describe "scheduler" do
describe ":thursday_invitations" do
let(:run_issue_invites) do
Rake::Task[:thursday_invitations].reenable
Rake.application.invoke_task :thursday_invitations
end
before do
Rake.application.rake_require 'tasks/scheduler'
Rake::Task.define_task(:environment)
Date.today.should_receive(:wday).and_return(4) ###MY NEMESIS CODE LINE
end
context "on thursday" do
it "issues invitations" do
expect(Date.today.wday).to eq(4) ###THE VERIFICATION TEST THAT KEEPS FAILING
run_issue_invites
expect(<other_stuff_to_test>).to <return_properly>
end
end
end
end
So, the real key of this is mocking out the Date.today.wday. Because I want to be able to run my spec on any day of the week, I need to mock/stub out this method to always return "4" (the day-number for Thursday in Rails). So, I initially setup my test to first verify that it is receiving a "4" (the assertion in the test). If today is, say, Friday (which it is) and I run the test, it fails saying that it expected "4" but got "5". That is, it is not returning the value that I want it to when I receive the method. I have tried stubbing with similar ineffective results. Normally, mocking is a breeze, but what seems to be the hangup is .wday which operates on Date.today.
Because this is a rake task (which I'm not as familiar with mocking), I may have to specify something further, but I haven't been able to get to the bottom of it...
Let me know if you need any other clarifying information.
I believe the reason you're not seeing the behavior you expect is that the object you are mocking is the not the same object under test.
In a Rails 4+ environment, this is what I see on the rails console:
[1]> Date.today.object_id
70104549170200
[2]> Date.today.object_id
70104552970360
The fact that the object_id is different in subsequent calls to Date.today means that each call returns a new object. So Date.today.should_receive(:wday).and_return(4) is setting an expectation on an object that will never be used again.
You'll need to rewrite your spec to ensure the same object is returned by Date.today each time. Here's one solution, omitting other parts of your example for clarity:
let!(:today) { Date.today }
before do
Date.stub(:today).and_return(today)
today.should_receive(:wday).and_return(4)
end
it "issues invitations" do
expect(Date.today.wday).to eq(4)
end
I was upgrading our code base to use rspec 3.1.0 and was following the docs here:
https://relishapp.com/rspec/docs/upgrade
One of the existing tests I get the following error after running transpec.
"with must have at least one argument. Use no_args matcher to set the expectation of receiving no arguments."
Here is the test.
it 'does something' do
expect(my_method).to receive(:resource)
.with { |path| path.include? 'test' }.and_return({})
end
Does the new synatx not receive a block anymore?
This was deprecated in version 2.99 and removed in rspec 3. You can see the details here: https://github.com/rspec/rspec-mocks/issues/377.
You can accomplish the same test with:
it 'does something' do
expect(my_object).to receive(:resource).with(/test/).and_return({})
end
Is there a way to turn off outputting pending tests in Rspec (rspec 3, specifically)? Rather than having to tag everyone and skipping them.
Perhaps a --pending type command for .rspec?
If you want a spec not to be run at all in rspec 3 you should use skip rather than pending
For some reason, RSpec is not recognizing assertions in one of my spec files - but runs the print statement around it.
To start the spec test, on the terminal:
rspec spec/lib/slots_scheduler_spec.rb
Part of the spec file that asserts... (is part of a loop)
print "#{slots_result[0].date} #{slot.date}\n"
slots_result[0].date.should == slot.date
And what I see on the console...
....
2012-11-18 2012-11-11
2012-11-25 2012-11-11
No examples found.
Finished in 0.00005 seconds
0 examples, 0 failures
If something is wrong, I expect some other message than '0 examples, 0 failures'. Why are my tests ignored like this?
You Haven't Defined an Example Group
Your code, as posted above, has no example groups. Example groups require a describe or context block, and a specify or it block for each test in order to work.
Your print statements work because they are valid Ruby. However, the RSpec DSL requires more from you before it will result in an actual test being performed.
When I run my model specs and controller specs separately, it's fine. When I run them together, I get a stack overflow, literally :)
$ bundle exec rspec --fail-fast spec/models
........
Finished in 0.44274 seconds
8 examples, 0 failures
$ bundle exec rspec --fail-fast spec/controllers
..
Finished in 0.99339 seconds
2 examples, 0 failures
$ bundle exec rspec --fail-fast spec
F
Failures:
1) HerpController derp derp example
Failure/Error: Unable to find matching line from backtrace
SystemStackError:
stack level too deep
# /Users/jared/.rvm/gems/ruby-1.9.2-p290/gems/actionpack-3.2.1/lib/abstract_controller/layouts.rb:359
Finished in 0.02241 seconds
1 example, 1 failure
How do I even begin to debug this? Thanks.
Removing half of my specs at a time turned up the problem. I suppose this is an example of bisect debugging. Thanks to Frederick Cheung, whose comment suggested this approach.
For posterity, this was the problem.
include Rails.application.routes.url_helpers
describe "Attendee#next_page" do
end
Apparently, includes go inside the describe
describe "Attendee#next_page" do
include Rails.application.routes.url_helpers
end
I have a lot to learn about rspec. :)
You can either put a debugger statement in your code and debug that way, or just start using puts "got here" in the places of your code that you know are being run. I would suggest using something meaningful instead of "got here" too :-)
I'd start either with puts or raise statements at key points in your code so you can start to narrow down which line is causing the problem. Once you start getting close, you can comment out one line at a time to figure out which line the problem disappears with - as soon as you've got it down to one line, you can figure out what that line is doing that Ruby doesn't like.
In general terms of where to start, "Stack level too deep" is usually an infinite loop or infinite recursion problem - I'd imagine that there's something going on where a model is invoking a controller that's invoking the model, or vice-versa. No way to know for sure until you start commenting out lines, but any place where you've got function calls is going to belong on your suspect short list. Good luck!
Possibly you can get "Unable to find matching line from backtrace" error in case you are checking some var which wasn't initialised actually
In this example pay attention to var observation which is not initialised in the wrong snippet
wrong snippet
describe "GET index" do
it "assigns all observations as #observations" do
get :index, {}, valid_session
assigns(:observations).should eq([observation])
end
end
fixed example (line 3)
describe "GET index" do
it "assigns all observations as #observations" do
observation = Observation.create! valid_attributes
get :index, {}, valid_session
assigns(:observations).should eq([observation])
end
end
Sometimes we rely on using let as initializer, but forget to add it e.g.
let(:observation) {FactoryGirl.create(:observation)}