Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

instance_spy breaks when using accessors in JRuby #919

Closed
doozr opened this issue Apr 9, 2015 · 7 comments
Closed

instance_spy breaks when using accessors in JRuby #919

doozr opened this issue Apr 9, 2015 · 7 comments

Comments

@doozr
Copy link

doozr commented Apr 9, 2015

When using JRuby 1.7.19 it is impossible to assign attributes when using instance_spy. The attributes work fine when using an instance_double as a null object. The test case is:

class SingleAccessor

  attr_accessor :should_be_assignable

end

describe SingleAccessor do

  it "allows an instance_spy accessor to be assigned" do
    instance_spy("SingleAccessor").should_be_assignable = "value"
  end

  it "allows a double as null object accessor to be assigned" do
    double("SingleAccessor").as_null_object.should_be_assignable = "value"
  end

end

With this result:

Failures:

  1) SingleAccessor allows an instance_spy accessor to be assigned
   Failure/Error: instance_spy("SingleAccessor").should_be_assignable = "value"
   ArgumentError:
     Wrong number of arguments. Expected 0, got 1.
   # ./spec/assign_to_mock_accessor_spec.rb:10:in `(root)'
   # ./spec/spec_helper.rb:96:in `(root)'
   # ./spec/spec_helper.rb:96:in `(root)'

Finished in 0.023 seconds (files took 1.62 seconds to load)
2 examples, 1 failure

Failed examples:

rspec ./spec/assign_to_mock_accessor_spec.rb:9 # SingleAccessor allows an instance_spy accessor to be assigned

The following versions are used:

jruby 1.7.19 (1.9.3p551) 2015-01-29 20786bd on Java HotSpot(TM) 64-Bit Server VM 1.6.0_31-b04 +jit [linux-amd64]
rspec 3.2.3
rspec-mocks 3.2.1

It worked fine with rspec 3.1.7 and rspec-mocks 3.1.3

@myronmarston
Copy link
Member

This is due to a bug in JRuby -- see the issue linked above. It worked fine on rspec-mocks 3.1 because on 3.0 and 3.1 we weren't verifying arguments for calls to null-object doubles. #829 fixed that but has the side effect of not working in this case on JRuby due to the JRuby bug.

The attributes work fine when using an instance_double as a null object.

Actually, it fails for instance_double(...).as_null_object, too (which is a relief: that's all instance_spy is so it was confusing me that it would fail for one but not the other!). Your spec above uses double(...).as_null_object, which is not a verifying double.

I'm not sure what to do about this yet...if the runtime lies to us and tells us a method takes no parameters, how are we supposed to know it's lied to us?

@myronmarston
Copy link
Member

Hmm, looks like the arity is still correct on JRuby...maybe we can use that.

@doozr
Copy link
Author

doozr commented Apr 9, 2015

Ah, my mistake. Yes, you are correct, it doesn't work with instance_double either. My apologies. I'll keep an eye on the JRuby bug.

@myronmarston
Copy link
Member

It appears that JRuby does not have this bug when you manually define the writer method (e.g. def should_be_assignable=(value); @should_be_assignable = value; end), so you might switch to that while we keep thinking about if we're going to do anything to work around this.

@myronmarston
Copy link
Member

Looks like jruby/jruby#2816 has already been fixed! They've added it to the JRuby 1.7.20 milestone which suggests a fix will come in the next JRuby 1.7 release.

Given that it's being addressed in JRuby so promptly, I don't think we should expend effort to work around it. Closing.

@doozr
Copy link
Author

doozr commented Apr 9, 2015

Good to know! For the time being I'll leave my 1 unchecked double (it's not critical to the test anyway) but will let the team know about the manual definition workaround. Cheers.

myronmarston added a commit to rspec/rspec-support that referenced this issue Jul 20, 2015
See jruby/jruby#2816 and rspec/rspec-mocks#919 for
a discussion of the bug. This is affecting us now that
I’m trying to enable partial double verification for
rspec-core (rspec/rspec-core#2032) so I thought it worth
addressing.
myronmarston added a commit to rspec/rspec-support that referenced this issue Jul 20, 2015
See jruby/jruby#2816 and rspec/rspec-mocks#919 for
a discussion of the bug. This is affecting us now that
I’m trying to enable partial double verification for
rspec-core (rspec/rspec-core#2032) so I thought it worth
addressing.
myronmarston added a commit to rspec/rspec-support that referenced this issue Jul 21, 2015
See jruby/jruby#2816 and rspec/rspec-mocks#919 for
a discussion of the bug. This is affecting us now that
I’m trying to enable partial double verification for
rspec-core (rspec/rspec-core#2032) so I thought it worth
addressing.
@betesh
Copy link
Contributor

betesh commented Aug 25, 2017

I'm running a jruby-1.7.22 Rails app with the following rspec versions:

$ git grep rspec --  Gemfile.lock  | grep "(3\.5"
Gemfile.lock:    rspec (3.5.0)
Gemfile.lock:    rspec-core (3.5.1)
Gemfile.lock:    rspec-expectations (3.5.0)
Gemfile.lock:    rspec-mocks (3.5.0)
Gemfile.lock:    rspec-rails (3.5.1)
Gemfile.lock:    rspec-support (3.5.0)

When I add this line:

mocks.verify_partial_doubles = true

I start getting errors such as this on numerous tests:

   Failure/Error: allow(MyJavaClass).to receive(:some_method).with("One Arg").and_return(some_object)
     Wrong number of arguments. Expected 0, got 1.
   # rspec-support-3.5.0/lib/rspec/support.rb:87:in `Support'
   # org/jruby/RubyProc.java:271:in `call'
   # rspec-support-3.5.0/lib/rspec/support.rb:96:in `notify_failure'
   # rspec-mocks-3.5.0/lib/rspec/mocks/error_generator.rb:327:in `notify'
   # rspec-mocks-3.5.0/lib/rspec/mocks/error_generator.rb:311:in `__raise'
   # rspec-mocks-3.5.0/lib/rspec/mocks/error_generator.rb:119:in `raise_invalid_arguments_error'
   # rspec-mocks-3.5.0/lib/rspec/mocks/verifying_message_expectation.rb:48:in `validate_expected_arguments!'
   # rspec-mocks-3.5.0/lib/rspec/mocks/verifying_proxy.rb:186:in `with_signature'
   # rspec-mocks-3.5.0/lib/rspec/mocks/verifying_message_expectation.rb:40:in `validate_expected_arguments!'
   # rspec-mocks-3.5.0/lib/rspec/mocks/verifying_message_expectation.rb:27:in `with'

My workaround is to add this to spec/spec_helper.rb, above RSpec.configure do |config|:

RSpec::Support.require_rspec_support 'ruby_features'
module RSpec::Support::RubyFeatures
  module_function
  def optional_and_splat_args_supported?
    false
  end
end

This fixed all the tests except the ones that use allow/expect_any_instance_of (at least on my dev machine--it did not fix it on my CI server, probably because we're running rspec slightly differently there and may have already loaded rspec-mocks before this method is redefined).

JonRowe pushed a commit to rspec/rspec-support that referenced this issue Jun 10, 2019
See jruby/jruby#2816 and rspec/rspec-mocks#919 for
a discussion of the bug. This is affecting us now that
I’m trying to enable partial double verification for
rspec-core (rspec/rspec-core#2032) so I thought it worth
addressing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants