I've added the following allow statement to spec_helper.rb to fix an issue in my codebase where tons of specs had added expect().receive on the metrics class making tests brittle to new metrics calls in underlying classes.
allow(MetricsClass).to receive(:increment).with(any_args)
Unfortunately, I'm running in errors
ArgumentError:
Wrong number of arguments. Expected 1, got 2.
The function definition:
def self.increment(counter_name, by: 1, **tags)
The line in the code where this failure happens:
MetricsClass.increment("string", **info)
Info itself is a hash
puts info
{"class/method"=>true}
ruby 2.7.6
rspec 3.12.0
Relevant RSpec configuration:
RSpec.configure do |config|
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
end
Related
test_spec.rb: (from FakeFS example)
require 'fakefs/spec_helpers'
describe 'Test' do
include FakeFS::SpecHelpers
it 'should fail' do
expect(1).to eq(2)
end
end
describe 'Test2' do
it 'should fail' do
expect(1).to eq(2)
end
end
rspec spec/test_spec.rb returns superclass mismatch for class File for the first test and normal expected: 2 got: 1 in the second case. Matcher changing (e.g. be_kind_of(String)) does not affect the result. Why does this happen, and how can it be fixed?
ruby -v
ruby 2.4.0dev (2016-03-19 trunk 54188) [x86_64-linux]
I just had this issue, and the accepted answer did not help me.
But I did eventually solve the issue by adding the following line to the top of my spec_helper.rb:
require 'pp'
I have a .rspec file with the following line to ensure spec_helper is loaded always:
--require spec_helper
It is documented in the FakeFS readme that you need to require pp before fakefs in order to avoid this problem, but I did not require pp myself. It must have been required implicitly by some other gem I use*.
Thus by explicitly requiring pp before fakefs, my specs now run as they should.
* I suspect RSpec uses pp for pretty printing error messages, as I could cause the exception in the line expect(true).to eq false
Thanks #d.g for link to fakefs issue. Things that works:
Gemfile
gem 'fakefs', require: 'fakefs/safe'
spec/spec_helper.rb
require 'fakefs/spec_helpers'
RSpec.configure do |config|
config.include FakeFS::SpecHelpers, fakefs: true
end
test_spec.rb
require_relative 'spec_helper.rb'
describe 'Test', fakefs: true do
it 'should fail' do
expect(1).to be_kind_of(String)
end
end
I'm setting up a standalone RSpec/Capybara test suite integrated with SauceLabs, but the instructions in the documentation don't seem to be working for me.
Here are the relevant parts of my spec_helper.rb:
require 'capybara'
require 'capybara/rspec'
require 'sauce/capybara'
Sauce.config do |config|
config[:browsers] = [
[ "OSX 10.10", "Safari", "8" ]
]
end
Capybara.default_driver = :sauce
And here's the feature (not_found_spec.rb):
feature 'Enroll: 404', :sauce => true do
before :each do
#nonexistent_curriculum = FactoryGirl.build :curriculum
#enroll = Enroll.new
end
context 'When I visit a page that does not exist' do
scenario 'I see a Not Found message' do
#enroll.go #nonexistent_curriculum
expect(#enroll.not_found).to be_visible
end
end
end
When I then run rspec, the specs run and pass, but no metadata of any kind is recorded. All I see on SauceLabs is "Unnamed Ruby job".
What am I missing?
When you run
bundle exec rake sauce:install:spec
it creates a sauce_helper.rb which is then typically required from the end of your rails_helper.rb or spec_helper.rb depending on what *_helper.rb files you have. It looks like you copied the Sauce config part from sauce_helper into your spec_helper but you haven't shown that you have
require "sauce"
in there which is in the generated sauce_helper. Without requiring "sauce" it may be that sauce/rspec/rspec.rb is not getting required which is where all the hooks into rspec for tests with sauce: true are set up.
I'm using rspec to test my Sinatra app. The app is super simple, and so are the tests, but when I run rspec from the CLI, it just starts the app server. I've never had this happen.
Here's what my spec_helper.rb looks like:
#spec/spec_helper.rb
require File.expand_path '../../app.rb', __FILE__
ENV['RACK_ENV'] = "test"
require 'rspec'
require 'rack/test'
set :environment, :test
set :run, false
set :raise_errors, true
set :logging, false
module RSpecMixin
def app
App.new
end
end
RSpec.configure do |config|
config.color_enabled = true
config.tty = true
config.formatter = :documentation
config.include Rack::Test::Methods
config.include RSpecMixin
end
And my spec is just
require 'spec_helper'
describe "My Sinatra Application" do
it "should allow accessing the home page" do
expect(1).to eq(1)
end
end
I can't get rspec to run.
What I've tried:
I've tried the recommendations in this Sinatra testing guide. Also the rspec Sinatra test recipe. In this blog post, the set :run, false looked promising, but no dice. Then I thought, I'll just define a rake task. Putting the rspec gem in the test group and setting the RACK_ENV to test. All these things just start the app server:
$ rake spec
[2014-03-08 22:06:38] INFO WEBrick 1.3.1
[2014-03-08 22:06:38] INFO ruby 2.0.0 (2013-02-24) [x86_64-darwin11.4.2]
== Sinatra/1.4.4 has taken the stage on 4567 for development with backup from WEBrick
[2014-03-08 22:06:38] INFO WEBrick::HTTPServer#start: pid=21538 port=4567
Halp?
Try removing the new() from your def app:
module RSpecMixin
def app
App
end
end
An other way to create your app for testing is something like this:
APP = Rack::Builder.parse_file('config.ru').first
module RSpecMixin
def app
APP
end
end
Obvious this works only if you use config.ru.
I found the answer. It's embarrassing, but I was switching back and forth between the modular and classic style deciding which I liked best, and I had left an errant App.run! call at the bottom of my app.rb file.
The following code raises an error: undefined method 'any_instance' for String:Class
require 'rspec'
RSpec.configure do |config|
config.mock_with :rspec
end
describe String do
it 'stubs' do
String.any_instance.stub(:foo).and_return(1)
''.foo.should eq(1)
end
end
How can I include the Mocks module into the Class or Object class?
any_instance was recently added to rspec, so your example now works for me as it is with rspec 2.7.
Update for rspec 3:
The new way to do this is
allow_any_instance_of(String).to receive(:foo).and_return(1)
Here is more any_instance documentation: https://relishapp.com/rspec/rspec-mocks/docs/working-with-legacy-code/any-instance
With RSpec Mocks in versions previous to 2.6.0, you cannot do it. However you can use any_instance with Mocha(as seen here) or in later versions of Rspec.
In your spec/spec_helper.rb
Make sure you have this line:
config.mock_with :mocha
uncommented.
I have been following the 15 TDD steps to create a Rails application guide - but have run into an issue I cannot seem to resolve. For the functional test of the WordsController, I have the following code:
class WordsControllerTest < ActionController::TestCase
test "should get learn" do
get 'learn'
assert_response :success
end
test "learn passes a random word" do
some_word = Word.new
Word.expects(:random).returns(some_word)
get 'learn'
assert_equal some_word, assigns('word')
end
end
In the Word class I have the following code:
class Word < ActiveRecord::Base
def self.random
all = Word.find :all
all[rand(all.size)]
end
end
When I run the tests, I experience the following error (shortened for brevity):
1) Failure: unexpected invocation: Word(...).random() satisfied expectations:
- expected exactly once, already invoked once: Word(...).random()
I have tried changing changing the order of the tests along with a multitude of other things, but time and time again I continue to receive the same test failure - that Word.random() has already been invoked.
I'm running Rails 3.0 beta 4 and Mocha 0.9.8. I've searched long and hard for a solution to my problem, but I can't seem to find it. I'm new to Ruby/Rails so am rather unfamiliar with the language and the frameworks.
Thanks in advance!
mocha needs to be loaded last. I struggled a lot with this problem too.
#Gemfile
group :test
gem 'mocha', '~>0.9.8', :require => false
...
end
and
test_helper.rb
....
#at the very bottom
require 'mocha'
I had the same problem, mocked functionality was not isolated to a test, it seems to be a problem with the load order of Mocha.
I had some issues getting Mocha to work with Rails3. I found a few stackoverflow posts regarding, but didn't stumble across the solution until I found a post on agoragames.com
Basically, in the Gemfile of your project, the require for Mocha should look like:
gem 'mocha', :require => false
Then in test/test_helper.rb, add a require line for mocha:
...
...
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
require 'mocha'
class ActiveSupport::TestCase
...
...
I think the require line for mocha in the Gemfile means that you need to already have mocha installed as a gem, bundler won't take care of it for you.
How are you requiring mocha? Are you using bundler? It sounds a bit as if the mocha teardown hook isn't being called?
Additionally, it seems mocha_teardown is not being called with rails31. Mocks that are setup are never removed... (this additional hack fixes it)
class ActiveSupport::TestCase
def teardown
super
Mocha::Mockery.instance.teardown
Mocha::Mockery.reset_instance
end
end
Those solutions didn't work for me on their own, using Ruby 2.2.2, Rails 4.2.2, mocha 1.1.0, shoulda-context 1.2.1, factory_girl_rails 4.5.0 and a few more testing related gems.
What did it was also moving these two lines at the bottom of my test_helper.rb:
require 'mocha/setup'
require 'mocha/test_unit'
I also removed require 'test/unit'. It appears that mocha/test_unit already does that for me.