Forum: RSpec Unable to stub a class method in a before_filter

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
059ed46172a087063ce26250e44c8627?d=identicon&s=25 Fernando Perez (fernando)
on 2008-11-04 20:38
Here is my spec:
--
describe Admin::ProductsController, "A visitor wants to access
admin/products" do

  before(:each) do
    @product = mock_model(Product, :traffic_available => 0)
    Product.stub!(:find_by_domain_name).and_return(@product)
  end

  it "should redirect to login path" do
    get :index
    response.should redirect_to(login_url)
  end

end
--

In my application.rb, I have the following before filter:
--
  def find_current_site
    @site = Site.find_by_domain_name(website_name)
    if @site.traffic_available < 0
      render :nothing => :true
    end
  end
--

As the test DB is empty and I don't use fixtures, it won't find any
site, therefore nil.traffic_available < 0 returns an error when running
the spec.

I thought I could stub out the find_by_domain_name method to return a
cooperative object with a traffic_available value, but it didn't work.

How can I do that correctly?

I have found a dirty workaround:
controller.stub!(:find_current_site).and_return(:true)

but I don't find it acceptable. I am not going to stub out all methods
in my app, that's nonsense.
5d38ab152e1e3e219512a9859fcd93af?d=identicon&s=25 David Chelimsky (Guest)
on 2008-11-04 20:47
(Received via mailing list)
On Tue, Nov 4, 2008 at 1:38 PM, Fernando Perez <lists@ruby-forum.com>
wrote:
>  it "should redirect to login path" do
>    @site = Site.find_by_domain_name(website_name)
> I thought I could stub out the find_by_domain_name method to return a
> cooperative object with a traffic_available value, but it didn't work.
>
> How can I do that correctly?
>
> I have found a dirty workaround:
> controller.stub!(:find_current_site).and_return(:true)
>
> but I don't find it acceptable. I am not going to stub out all methods
> in my app, that's nonsense.

I don't know if this will satisfy you or not, but you *could* write
that once and have it apply across your entire suite. Add this to
spec/spec_helper.rb (or equivalent):

Spec::Runner.configure do |config|
  config.before(:each, :type => :controller) do
    controller.stub!(:find_current_site).and_return(:true)
  end
end

That work?
Cdf378de2284d8acf137122e541caa28?d=identicon&s=25 Matt Wynne (mattwynne)
on 2008-11-04 20:53
(Received via mailing list)
On 4 Nov 2008, at 19:38, Fernando Perez wrote:
> Here is my spec:
> --
> describe Admin::ProductsController, "A visitor wants to access
> admin/products" do
>
>  before(:each) do
>    @product = mock_model(Product, :traffic_available => 0)
>    Product.stub!(:find_by_domain_name).and_return(@product)

Should this be Site.stub!(:find_by_domain_name)... ?
059ed46172a087063ce26250e44c8627?d=identicon&s=25 Fernando Perez (fernando)
on 2008-11-04 21:42
> That work?

It could. But in such case, how will I test my before_filter
independently?

My real problem is to stub the find_by_domain_name instance method.
059ed46172a087063ce26250e44c8627?d=identicon&s=25 Fernando Perez (fernando)
on 2008-11-04 21:46
Are the docs on mock outdated? I sometimes see mock_model, and sometimes
mock. Which one should be used?
059ed46172a087063ce26250e44c8627?d=identicon&s=25 Fernando Perez (fernando)
on 2008-11-04 21:51
Crap! I was stubbing Product, instead of Site! It all works now. Matt's
typo put me on the track!

But I will definitely use the trick Spec::Runner.configure do
|config|...
 to avoid having to type this stub in all my files.

Thanks.
Cdf378de2284d8acf137122e541caa28?d=identicon&s=25 Matt Wynne (mattwynne)
on 2008-11-04 21:59
(Received via mailing list)
On 4 Nov 2008, at 20:46, Fernando Perez wrote:

> Are the docs on mock outdated? I sometimes see mock_model, and
> sometimes
> mock. Which one should be used?

For mock_model, you need to look at the rspec-rails gem, which is a
separate library.

You actually have three choices when mocking an ActiveRecord model:
mock, mock_model and stub_model. mock() belongs to rspec's core
library, while the latter two come with the rails-specific extension
gem.

See here for the documentation on the two rails mocking methods:
http://rspec.rubyforge.org/rspec-rails/1.1.11/clas...

There's also a good blog post on David's blog about stub_model
http://blog.davidchelimsky.net/2008/5/27/rspec-1-1-4

HTH,
Matt
059ed46172a087063ce26250e44c8627?d=identicon&s=25 Fernando Perez (fernando)
on 2008-11-04 22:12
Ok I get it. I was wondering why mock_model was not showing up in
rspec's rdoc. Thanks for the clarification.
944f769c99deff7aa8bc3b5b93830b7a?d=identicon&s=25 Scott Taylor (Guest)
on 2008-11-04 22:28
(Received via mailing list)
On Nov 4, 2008, at 3:46 PM, Fernando Perez wrote:

> Are the docs on mock outdated? I sometimes see mock_model, and
> sometimes
> mock. Which one should be used?

mock_model is for ActiveRecord objects.  it's just a mock() call with
a random id stub set, and a :new_record? => false

Scott
This topic is locked and can not be replied to.