Need to clear Mocha expectation?

View: New views
3 Messages — Rating Filter:   Alert me  

Need to clear Mocha expectation?

by Yongsang Kim :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Folks,

I have a problem that I have been able to isolate into a small test
application.

The problem seems to be that when I set an expectation on the number of
times a method will be called in one describe block, the expectation is
still set in a different describe block.  My understanding was that
RSpec restored the state of objects and the end of a test, which I
interpreted as the end of a describe block (seeing that the scope of the
expectation ended).

Here is my test application:
: rails rspecproblem
: cd rspecproblem
<install rspec & rspec-rails>
: script/generate rspec_model Contest contest_name:string status:integer
contest_series_id:integer
: script/generate rspec_model ContestSeries series_name:string
: rake db:migrate
: autotest

I edited contest.rb and set the following:
class Contest < ActiveRecord::Base
  belongs_to :contest_series

  def getSeries
    ContestSeries.find(contest_series_id)
  end
end

I edited contest_series.rb and added the has_many statement:
class ContestSeries < ActiveRecord::Base
  has_many :contests
end


I then created the following spec file in spec/models/contest_spec.rb
that can be found at http://pastie.org/283936

The summary of the test spec is that there are two describe blocks.  The
first block creates a Contest and assigns it to a ContestSeries.  For
the sake of the example, I then call ContestSeries.find().

The second block sets an expectation on ContestSeries that the find
method will be called only once.

This causes the following error:

Mocha::ExpectationError in 'Contest should demonstrate that the stub is
not cleared'
unexpected invocation: ContestSeries(id: integer, series_name: string,
created_at: datetime, updated_at: datetime).find(1)
satisfied expectations:
- expected exactly once, already invoked once: ContestSeries(id:
integer, series_name: string, created_at: datetime, updated_at:
datetime).find(1000)

Playing around with some variations, I have found that if I change the
code in line 24 to:

ContestSeries.expects(:find).at_least(1)

then no error is generated, but this isn't really what I want.  I want
to be confident that the "getSeries" call (which is really only a
simplification of the actual code) gets the correct ContestSeries.

Have I misunderstood how to use this stubbing behavior?  Is there a way
to correctly clear such expectations in an after block?

Many thanks,

Peter
--
Posted via http://www.ruby-forum.com/.
_______________________________________________
rspec-users mailing list
rspec-users@...
http://rubyforge.org/mailman/listinfo/rspec-users

Re: Need to clear Mocha expectation?

by David Chelimsky-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Oct 2, 2008 at 5:20 PM, Peter Degen-Portnoy
<lists@...> wrote:

> Hi Folks,
>
> I have a problem that I have been able to isolate into a small test
> application.
>
> The problem seems to be that when I set an expectation on the number of
> times a method will be called in one describe block, the expectation is
> still set in a different describe block.  My understanding was that
> RSpec restored the state of objects and the end of a test, which I
> interpreted as the end of a describe block (seeing that the scope of the
> expectation ended).
>
> Here is my test application:
> : rails rspecproblem
> : cd rspecproblem
> <install rspec & rspec-rails>
> : script/generate rspec_model Contest contest_name:string status:integer
> contest_series_id:integer
> : script/generate rspec_model ContestSeries series_name:string
> : rake db:migrate
> : autotest
>
> I edited contest.rb and set the following:
> class Contest < ActiveRecord::Base
>  belongs_to :contest_series
>
>  def getSeries
>    ContestSeries.find(contest_series_id)
>  end
> end
>
> I edited contest_series.rb and added the has_many statement:
> class ContestSeries < ActiveRecord::Base
>  has_many :contests
> end
>
>
> I then created the following spec file in spec/models/contest_spec.rb
> that can be found at http://pastie.org/283936
>
> The summary of the test spec is that there are two describe blocks.  The
> first block creates a Contest and assigns it to a ContestSeries.  For
> the sake of the example, I then call ContestSeries.find().
>
> The second block sets an expectation on ContestSeries that the find
> method will be called only once.
>
> This causes the following error:
>
> Mocha::ExpectationError in 'Contest should demonstrate that the stub is
> not cleared'
> unexpected invocation: ContestSeries(id: integer, series_name: string,
> created_at: datetime, updated_at: datetime).find(1)
> satisfied expectations:
> - expected exactly once, already invoked once: ContestSeries(id:
> integer, series_name: string, created_at: datetime, updated_at:
> datetime).find(1000)
>
> Playing around with some variations, I have found that if I change the
> code in line 24 to:
>
> ContestSeries.expects(:find).at_least(1)

You learn something new every day!

First, the fix: in spec_helper.rb

Spec::Runner.configure do |config|
  ...
  config.mock_with :mocha
  ...
end

The problem is that rspec needs to know that you're using mocha in
order for it to call the mocha methods needed to verify and reset at
the end of each example.

The reason that the examples that use mocha methods seem to recognize
those mocha methods is that, as I only just learned, rails *might*
automatically load mocha in the test environment (depending on a few
other factors in your system) implicitly without any direction to do
so. If you're a mocha user, this is a good thing. Not so great if
you're using other frameworks :) C'est la vie.

Cheers,
David



>
> then no error is generated, but this isn't really what I want.  I want
> to be confident that the "getSeries" call (which is really only a
> simplification of the actual code) gets the correct ContestSeries.
>
> Have I misunderstood how to use this stubbing behavior?  Is there a way
> to correctly clear such expectations in an after block?
>
> Many thanks,
>
> Peter
> --
> Posted via http://www.ruby-forum.com/.
> _______________________________________________
> rspec-users mailing list
> rspec-users@...
> http://rubyforge.org/mailman/listinfo/rspec-users
>
_______________________________________________
rspec-users mailing list
rspec-users@...
http://rubyforge.org/mailman/listinfo/rspec-users

Re: Need to clear Mocha expectation?

by Yongsang Kim :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

David Chelimsky wrote:

> First, the fix: in spec_helper.rb
>
> Spec::Runner.configure do |config|
>   ...
>   config.mock_with :mocha
>   ...
> end
>

Indeed!  There was even such a line ready to be uncommented in
spec_helper.rb

Thank you so very much!  That did indeed fix the problem nicely.

- Peter
--
Posted via http://www.ruby-forum.com/.
_______________________________________________
rspec-users mailing list
rspec-users@...
http://rubyforge.org/mailman/listinfo/rspec-users
LightInTheBox - Buy quality products at wholesale price!