Deprecation Warnings: `any_instance`

181 views
Skip to first unread message

Arup Rakshit

unread,
Jul 6, 2014, 7:59:19 AM7/6/14
to rs...@googlegroups.com
Look at the code below :-

#!/usr/bin/env ruby

class Foo
def baz
11
end
end


Now my Rspec code :-

require_relative "../test.rb"

describe Foo do
before { Foo.any_instance.stub(:baz).and_return(20) }

it "defines #foo dynamically" do
expect_any_instance_of(Foo).to receive(:baz).and_return(20)
subject.baz
end
end

And finally I got :-

Deprecation Warnings:

Using `any_instance` from rspec-mocks' old `:should` syntax without explicitly
enabling the syntax is deprecated. Use the new `:expect` syntax or explicitly
enable `:should` instead. Called from /home/arup/Ruby/spec/test_spec.rb:4:in
`block (2 levels) in <top (required)>'.


If you need more of the backtrace for any of these deprecations to
identify where to make the necessary changes, you can configure
`config.raise_errors_for_deprecations!`, and it will turn the
deprecation warnings into errors, giving you the full backtrace.

1 deprecation warning total

Finished in 0.04004 seconds (files took 0.47731 seconds to load)
1 example, 0 failures
arup@linux-wzza:~/Ruby>



What else way I can write this ?

--
================
Regards,
Arup Rakshit
================
Debugging is twice as hard as writing the code in the first place. Therefore,
if you write the code as cleverly as possible, you are, by definition, not
smart enough to debug it.

--Brian Kernighan

Antonio Antillon

unread,
Jul 6, 2014, 12:23:08 PM7/6/14
to rs...@googlegroups.com
Hi Arup,

try doing this in your foo_spec.rb

describe Foo do
  before { allow(Foo).to receive(:baz).and_return(20) }

  # all other lines as they are
end




--
You received this message because you are subscribed to the Google Groups "rspec" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rspec+un...@googlegroups.com.
To post to this group, send email to rs...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/rspec/29269646.tYJQcMUKxg%40linux-wzza.site.
For more options, visit https://groups.google.com/d/optout.

Xavier Shay

unread,
Jul 6, 2014, 12:30:38 PM7/6/14
to rs...@googlegroups.com

On 6/07/2014 9:23 am, Antonio Antillon wrote:
Hi Arup,

try doing this in your foo_spec.rb

describe Foo do
  before { allow(Foo).to receive(:baz).and_return(20) }

  # all other lines as they are
end


should be

allow_any_instance_of(Foo).to receive(:baz).and_return(20)

... right?

Xavier

(obligatory reminder of this paragraph from the docs: https://relishapp.com/rspec/rspec-mocks/v/3-0/docs/working-with-legacy-code/any-instance

This feature is sometimes useful when working with legacy code, though in general we
discourage its use for a number of reasons:

  • The rspec-mocks API is designed for individual object instances, but this feature operates on entire classes of objects. As a result there are some sematically confusing edge cases. For example, in expect_any_instance_of(Widget).to receive(:name).twice it isn't clear whether each specific instance is expected to receive name twice, or if two receives total are expected. (It's the former.)
  • Using this feature is often a design smell. It may be that your test is trying to do too much or that the object under test is too complex.
  • It is the most complicated feature of rspec-mocks, and has historically received the most bug reports. (None of the core team actively use it, which doesn't help.)

)


Arup Rakshit

unread,
Jul 6, 2014, 1:45:46 PM7/6/14
to rs...@googlegroups.com
On Sunday, July 06, 2014 09:23:06 AM Antonio Antillon wrote:
> Hi Arup,
>
> try doing this in your foo_spec.rb
>
> describe Foo do
> before { allow(Foo).to receive(:baz).and_return(20) }
>
> # all other lines as they are
> end
>

Basically this example is a small part of my actual code. I generally sometime
don't want to call the original method, rather I stub it, the way I set the
example in my original post. Then from the example, I call the method and
expect it to show the same behavior the way I stubbed it.

In Rspec 3 it seems *stubbing* is not possible. *stubbing* and *expectation*
is merged in the same line of code, like below and it works too :-

describe Foo do
it "invokes #baz" do
expect_any_instance_of(Foo).to receive(:baz).and_return(20)
subject.baz
end
end

But this code is not much expressive than the first one I wrote. In the first
one, I stub the method, with return value.

Then I call it and matched all things with the expectations, which it seems no
more possible in Rspec.

Xavier Shay

unread,
Jul 6, 2014, 1:53:32 PM7/6/14
to rs...@googlegroups.com

On 6/07/2014 9:45 am, Arup Rakshit wrote:
> On Sunday, July 06, 2014 09:23:06 AM Antonio Antillon wrote:
>> Hi Arup,
>>
>> try doing this in your foo_spec.rb
>>
>> describe Foo do
>> before { allow(Foo).to receive(:baz).and_return(20) }
>>
>> # all other lines as they are
>> end
>>
> Basically this example is a small part of my actual code. I generally sometime
> don't want to call the original method, rather I stub it, the way I set the
> example in my original post. Then from the example, I call the method and
> expect it to show the same behavior the way I stubbed it.
>
> In Rspec 3 it seems *stubbing* is not possible. *stubbing* and *expectation*
> is merged in the same line of code, like below and it works too :-
This is what `allow` does. It is different from `expect`. Try it:

allow_any_instance_of(Foo).to receive(:baz).and_return(20)

Arup Rakshit

unread,
Jul 6, 2014, 2:16:02 PM7/6/14
to rs...@googlegroups.com
On Sunday, July 06, 2014 10:59:38 AM Xavier Shay wrote:
> On 6/07/2014 9:45 am, Arup Rakshit wrote:
> > On Sunday, July 06, 2014 09:23:06 AM Antonio Antillon wrote:
> >> Hi Arup,
> >>
> >> try doing this in your foo_spec.rb
> >>
> >> describe Foo do
> >>
> >> before { allow(Foo).to receive(:baz).and_return(20) }
> >>
> >> # all other lines as they are
> >>
> >> end
> >
> > Basically this example is a small part of my actual code. I generally
> > sometime don't want to call the original method, rather I stub it, the
> > way I set the example in my original post. Then from the example, I call
> > the method and expect it to show the same behavior the way I stubbed it.
> >
> > In Rspec 3 it seems *stubbing* is not possible. *stubbing* and
> > *expectation* is merged in the same line of code, like below and it works
> > too :-
> This is what `allow` does. It is different from `expect`. Try it:
>
> allow_any_instance_of(Foo).to receive(:baz).and_return(20)

Nice to know. Could you elaborate what is the diff between
*expect_any_instance_of* and *allow_any_instance_of* ... Which one to use in
what case... Example code may help also for better understanding....

Xavier Shay

unread,
Jul 6, 2014, 2:24:30 PM7/6/14
to rs...@googlegroups.com

On 6/07/2014 10:15 am, Arup Rakshit wrote:
> On Sunday, July 06, 2014 10:59:38 AM Xavier Shay wrote:
>> On 6/07/2014 9:45 am, Arup Rakshit wrote:
>>> On Sunday, July 06, 2014 09:23:06 AM Antonio Antillon wrote:
>>>> Hi Arup,
>>>>
>>>> try doing this in your foo_spec.rb
>>>>
>>>> describe Foo do
>>>>
>>>> before { allow(Foo).to receive(:baz).and_return(20) }
>>>>
>>>> # all other lines as they are
>>>>
>>>> end
>>> Basically this example is a small part of my actual code. I generally
>>> sometime don't want to call the original method, rather I stub it, the
>>> way I set the example in my original post. Then from the example, I call
>>> the method and expect it to show the same behavior the way I stubbed it.
>>>
>>> In Rspec 3 it seems *stubbing* is not possible. *stubbing* and
>>> *expectation* is merged in the same line of code, like below and it works
>>> too :-
>> This is what `allow` does. It is different from `expect`. Try it:
>>
>> allow_any_instance_of(Foo).to receive(:baz).and_return(20)
> Nice to know. Could you elaborate what is the diff between
> *expect_any_instance_of* and *allow_any_instance_of* ... Which one to use in
> what case... Example code may help also for better understanding....

in your words, allow_any = stubbing, expect_any = expectation

This is described here:
https://relishapp.com/rspec/rspec-mocks/v/3-0/docs/working-with-legacy-code/any-instance
(follow the links to "Allow" and "Expect")

Cheers,
Xavier
>
>

Arup Rakshit

unread,
Jul 6, 2014, 3:16:28 PM7/6/14
to rs...@googlegroups.com
> > Nice to know. Could you elaborate what is the diff between
> > *expect_any_instance_of* and *allow_any_instance_of* ... Which one to use
> > in what case... Example code may help also for better understanding....
> in your words, allow_any = stubbing, expect_any = expectation
>
> This is described here:
> https://relishapp.com/rspec/rspec-mocks/v/3-0/docs/working-with-legacy-code/
> any-instance (follow the links to "Allow" and "Expect")
>
> Cheers,
> Xavier

That's helpful really. I am going through the Relish doco page by page. So
still couldn't reach to the page you linked. :-) But I got it clear. It seems,
I can change these 2 methods interchangeably. No difference in their use. Both
will run happily :-

RSpec.describe "allow_any_instance_of" do
context "with receive_messages" do
it "stubs multiple methods" do
allow_any_instance_of(Object).to receive_messages(:foo => 'foo', :bar =>
'bar')

o = Object.new
expect(o.foo).to eq('foo')
expect(o.bar).to eq('bar')
end
end
end

and

RSpec.describe "allow_any_instance_of" do
context "with receive_messages" do
it "stubs multiple methods" do
expect_any_instance_of(Object).to receive_messages(:foo => 'foo', :bar
=> 'bar')

o = Object.new
expect(o.foo).to eq('foo')
expect(o.bar).to eq('bar')
end
end
end

Only difference remains on people, who like allow_*, will use this, who don't
like it, will use expect_* ... :-)

Xavier Shay

unread,
Jul 6, 2014, 7:31:02 PM7/6/14
to rs...@googlegroups.com
`expect_` will raise if the message is never received, allow won't.

Arup Rakshit

unread,
Jul 7, 2014, 11:36:47 AM7/7/14
to rs...@googlegroups.com
>On Sunday, July 06, 2014 04:37:06 PM Xavier Shay wrote:
> `expect_` will raise if the message is never received, allow won't.

Yes. This is the difference, I have tested. Thanks Xavier
Reply all
Reply to author
Forward
0 new messages