Compound expectations stopped working rspec - ruby-on-rails

Recently my tests are started failing with following exception.
NoMethodError:
undefined method `and' for #<Capybara::RSpecMatchers::Matchers::HaveText:0x00007f97687dbe30>
Did you mean? end
My tests looks like
it "starts german but allows to be changed to english" do
within(".e-header") do
# german locale
expect(page).to have_content("Mein Anliegen").and not_have_content("My issue")
end
end
Rspec 3.10 documentation for compound expectations still supporting it. I am not sure why suddenly my tests started failing.

it looks like capybara will not include compound module if rspec expectations is not be defined (in other words, not require yet)
so try require "rspec/expectations" explicitly.
the reason:
it was due to the version range of RSpec we supported combined with the fact that a few people complained when we did because some people didn't want RSpec::Expectations. Most people don't run into this issue because they're using Capybara with rspec-rails.

A very similar error happened when I ran my test suite with Spring enabled:
undefined method `and' for #<Capybara::RSpecMatchers::Matchers::HaveSelector
The answer in the comment by Asad Ali helped, just added:
bundle add rspec-expectations --group test
And the specs work with Spring.

Related

Why is fixture_file_upload not available in RSpec (without ActiveRecord)?

I'm trying to test a file upload using RSpec 3.7 in a Rails 5.2 app, and the simplest recommendation I've seen (several places, including this SO post) is to use fixture_file_upload - which looks great, except that it doesn't seem to be available in my app, and I don't know why.
The only thing I can think of is that our app is not using ActiveRecord, it's using MongoID. But ActiveRecord shouldn't be required to use these methods... they're totally unrelated. Is there another new "ActiveSomething" library in Rails 5 that I'm missing? (this app was upgraded from a Rails 4 app...)
To explain my problem more concretely, I've tried putting:
let(:file) { fixture_file_upload('invalid_csv.csv') }
in one of my contexts, and it raises an exception:
undefined local variable or method 'fixture_path' for #<RSpec::ExampleGroups::...>
I tried defining config.file_fixture_path as outlined here, and that raises it's own exception:
undefined method `file_fixture_path=' for #<RSpec::Core::Configuration::...>
Does this work at all? Clearly I'm missing something...
I've fixed this by including their module on the RSpec config block:
RSpec.configure do |config|
#...
config.include ActionDispatch::TestProcess::FixtureFile
#...
end
this worked for me
Rack::Test::UploadedFile.new(Rails.root.join("spec/fixtures/doc.pdf"))

and_call_original used with allow_any_instance_of is not working after rspec upgrade to 3.1.0

I had a code in rspec 2.14.1 like
allow_any_instance_of(AnyClass).to receive(:some_method).and_call_original
with a corresponding message expectation
expect_any_instance_of(AnyClass).to receive(:some_method)
The above worked fine in rspec 2.14.1. After upgrade to rspec 3.1.0, the above code no longer works. It fails on the message expectation that some_method is not called even once
However if I change the stub like
allow_any_instance_of(AnyClass).to receive(:some_method).and_return(value)
it works fine in rspec 3.1.0.
I just wanted to understand why using and_call_original with allow_any_instance_of fails after rspec upgrade.
I can see from this link that and_call_original is only supported on partial doubles.
Does that mean using allow_any_instance_of is not partial double?
and_call_original does actually work when used with allow_any_instance_of.
Refer the specs for any_instance which gives us an idea of different ways of mocking or to un-stub using and_call_original here.
To answer my question above, the way I was using message expectation is wrong. It should be:
allow_any_instance_of(AnyClass).to(
receive(:any_method).and_call_original
)
expect(AnyClass.new.any_method).to eq(:any_method_value)
I was trying to use expect_any_instance_of instead of expect which caused the issue.

RSpec Stubbing Java Static Method ArgumentError

I am attempting to stub a Java static method in my specs for my JRuby class which imports some Java libraries. I get the following error for the method call:
Failure/Error: JCoDestinationManager.getDestination('properties')
ArgumentError:
Wrong number of arguments. Expected 0, got 1.
That's the JCo Java static method. I created a small spec file to try and isolate the issue:
require 'rails_helper'
describe SapClient do
let(:destination) { double(Java::ComSapConnJcoRt::RfcDestination) }
before do
allow(JCoDestinationManager).to receive(:getDestination).and_return destination
end
it 'can be created' do
c = SapClient.new
expect(c).to_not be_nil
end
end
If I add the with clause like so, I still get the same result.
allow(JCoDestinationManager).to receive(:getDestination).with('properties').and_return destination
The strange part to me is that I only encounter this project in rails. If I copy the code over to a Sinatra project and run these specs there, all is well. I created a new Rails project and a new Sinatra project and installed the same versions of RSpec, verified RSpec mocks were the same version, etc. and still saw the discrepancy in behavior.
When I throw in a pry and observe what happens when I just call
JCoDestinationManager.getDestination
With no arguments, I get the mock destination that I define. If I comment out the allow statement, I see a real RfcDestination get created.
While searching, only thing I saw that seemed close to what I'm observing here is from https://github.com/rspec/rspec-mocks/issues/919 but apparently the solution to this problem was a jruby issue that has since been fixed.
Rails Gemfile
Rails Gemfile.lock
Sinatra Gemfile
Sinatra Gemfile.lock

Mocha's regexp_matches missing some times

I'm having a hard time getting any consistant behavior from Mocha and the regexp_matches method. If autotest runs my entire test suite everything works fine. If I purposely cause the test containing the regexp_matches call to fail and then fix it I get a method_missing error on regexp_matches. If I then run the entire test suite again, everything is fine. The bigger problem is coming from Hudson (continuous integration). It runs the entire test suite but always says regexp_matches is missing and I don't know how to fix it.
My test:
test "if token is set during Account creation the long url should be created correctly" do
Account.any_instance.expects(:http_get).with("api.server.com", regexp_matches(%r(^http://.*/accounts/\d+/jobs$)))
account = Account.create name: "New Account", token: "NewToken"
end
The error:
test_if_token_is_set_during_Account_creation_the_long_url_should_be_created_correctly(AccountTest):
NoMethodError: undefined method `regexp_matches' for #<AccountTest:0x0000010162d0c0>
test/unit/account_test.rb:158:in `block in <class:AccountTest>'
I don't even know what other code to add here as I can't imagine what the cause is. For giggles I pasted require 'mocha' at the top of the test file but that didn't change anything.
I ran into this problem on a rails project when removing
require 'spec_helper'
I did this so that running the spec would not load the whole rails environment. This means that external dependencies have to be required or mocked. Mocha obviously needs to be required.
But even after specifying
require 'mocha'
I ran into the same method missing issue.
Ultimately, I solved it by including the parameter matchers module directly:
require_relative "../../../lib/some_class"
require "mocha"
include Mocha::ParameterMatchers
describe SomeClass do
it "should do things" do
...

Rails + RSpec problem

I have just installed Rspec and Rspec-rails. When i try to run the test, it says:
rake aborted!
Command /opt/local/bin/ruby -I"lib" "/opt/local/lib/ruby/gems/1.8/gems/rspec-1.3.0/bin/spec" "spec/controllers/free_controller_spec.rb" --options "/Volumes/Trash/dev/app/trunk/spec/spec.opts" failed
Full log here: http://pastie.org/939211
However, my second "test" application with sqlite works with it. I think the problem is in my DB.
My ruby version is 1.8.7, i use mysql as database.
My files:
specs/spec_helper.rb
config/environment.rb
config/environments/test.rb
List of my gems
My test is just:
require 'spec_helper'
describe FreeController do
it "should respond with success" do
get 'index'
response.should be_success
end
end
I really can't understand the error, so i don't know how to fix it..
Additional question: should i use a fixtures and ActiveRecord, if i going to use Machinist for creating test data? What should i do to disable them?
From your error log:
/app/models/thread.rb:1: superclass mismatch for class Thread (TypeError)
Is your model named Thread? You might have a name collision. Ruby has built-in class named Thread. Try renaming your model.

Resources