4

How do I stub an http request, like this one to the twitter api below, on a global scope so it's valid for all tests in a Test::Unit suite?

stub_request(:get, "https://api.twitter.com/1/users/show.json?screen_name=digiberber").
    with(:headers => {'Accept'=>'application/json', 'User-Agent'=>'Twitter Ruby Gem 1.1.2'}).
    to_return(:status => 200, :body => "", :headers => {})

This WebMock stub works within a TestCase subclass's setup() block, like

class MyTest < ActiveSupport::TestCase       
  setup do
    stub_request(...)...
  end
end

But doesn't get recognized if I put it within a global setup in TestCase itself:

require 'webmock/test_unit'
class ActiveSupport::TestCase  
  setup do
    stub_request(...)
  end
end

Which gives me the error:

NoMethodError: undefined method `stub_request' for ActiveSupport::TestCase:Class

I've also tried by patching the method def itself

def self.setup
  stub_request(...)
end

but it doesn't work either.

Something similar happens when I use FlexMock instead of WebMock. Seems to be a scope problem, but I can't figure out how to go around it. Ideas?

oliverbarnes
  • 2,111
  • 1
  • 20
  • 31
  • Sorry, just answered but missed that you're using Test::Unit. Anyway, take a look at FakeWeb. https://github.com/chrisk/fakeweb – d11wtq Jul 07 '11 at 04:27
  • wouldn't fakeweb have the same issue? register_uri() is very similar to webmock's stub_request(), and I'd need to run it globally as well – oliverbarnes Jul 07 '11 at 13:13
  • Perhaps you could abstract the HTTP request into a class or module method, which you could then easily mock or stub. – Wizard of Ogz Jul 07 '11 at 13:17
  • @Wizard of Ogz, actually that was my original approach - stubbing twitter gem's Twitter.user() with flexmock under global setup(). But flexmock() also doesn't get recognized :P. I think in both approaches I'm just stubbing in the wrong place, but can't figure out the correct one – oliverbarnes Jul 07 '11 at 17:54
  • ...I mean I'm just adding the stub call in the wrong place, where the mocking libs don't get recognized. I can't figure out where the correct place would be, or how to force the inclusion of those stubbing/mocking methods there. Tried FlexMock.flexmock(), for instance, just but Flexmock module just isn't there, though it's required (tried include()ing it, but no luck either) – oliverbarnes Jul 07 '11 at 18:02

3 Answers3

2

Using FakeWeb you could do something like this:

In *test/test_helper.rb*

require 'fakeweb'

class ActiveSupport::TestCase
  def setup
    # FakeWeb global setup
    FakeWeb.allow_net_connect = false # force an error if there are a net connection to other than the FakeWeb URIs
    FakeWeb.register_uri(:get, 
        "https://api.twitter.com/1/users/show.json?screen_name=digiberber",
        :body => "",
        :content_type => "application/json")
  end
  def teardown
    FakeWeb.allow_net_connect = true
    FakeWeb.clean_registry # Clear all registered uris
  end
end

With this, you can call to the registered fakeweb from any testcase.

tothemario
  • 5,851
  • 3
  • 44
  • 39
1

This post on different ways to setup() and teardown() led me to just do

class ActiveSupport::TestCase  
  def setup
    stub_request(...)
  end
end

hadn't thought of declaring it as an instance method. :P

oliverbarnes
  • 2,111
  • 1
  • 20
  • 31
0

The capybara driver Akephalos does support stubbing http calls. They call it filters.

http://oinopa.com/akephalos/filters.html

http://github.com/Nerian/akephalos

Nerian
  • 15,901
  • 13
  • 66
  • 96