Mock out Curl::Easy.perform? (in Curb) - ruby-on-rails

Is there a way to mock out Curb's Easy.perform method for unit testing? I use this to hit Facebook's graph API, and none of the http mock libs seem to support Curb.
What's the best approach here?

WebMock has recently added Curb support. :)
http://github.com/bblimke/webmock

I really think fakeWeb is a great way to fake out network calls; Whatever HTTP library you use, you'll just specify what response text and code you want to receive.
Described as:
FakeWeb is a helper for faking web
requests in Ruby. It works at a global
level, without modifying code or
writing extensive stubs
Example from the github repository:
FakeWeb.register_uri(:get, "http://example.com/test1", :string => "Hello World!")
Net::HTTP.get(URI.parse("http://example.com/test1"))
=> "Hello World!"
Net::HTTP.get(URI.parse("http://example.com/test2"))
=> FakeWeb is bypassed and the response from a real request is returned

Related

Grails testing Curl like post

I tend to test my API using Curl.
Is there a way in Grails that I can make a test just posts to my API and then I can evaluate the results.
I have tried Spock testing and this didn't work.
I cannot seem to find a simple example on the internet.
Has anyone done similar?
It really depends on what kind of testing you want to do. If you want to send requests to your app using curl you can. I do that for a lot of things. If you want automated tests, you can do that too. Spock is the default unit testing framework but you could use others.
See the controller unit testing docs at http://grails.org/doc/latest/guide/testing.html#unitTestingControllers. There are examples there which show how to test different HTTP request methods, JSON and XML request bodies, JSON and XML responses, AJAX, mime types, etc.
I hope that helps.

How to test for API errors?

My rails app talks to a couple different APIs, and I'd like to write tests to make sure that errors are being handled properly in case there is a problem with a request. For example, if the service is down and not reachable.
Is there a way I can simulate an error coming back from a service even though it might be fine during the test?
The webmock gem helps you with this. For your specific question scroll down to "Response with custom status message".
stub_request(:any, "www.example.com").to_return(:status => [500, "Internal Server Error"])
req = Net::HTTP::Get.new("/")
Net::HTTP.start("www.example.com") { |http| http.request(req) }.message # ===> "Internal Server Error"
I've used this gem with Rspec and Test::Unit. The biggest drawback is that the matching logic which decides what requests apply to a particular mock doesn't always work as you'd expect. It's a minor gripe though. The gem is a net-positive, and much better than trying to hit a live service from a test case.
You can use a mock instead of the real service, and make it give back an error.

Use fakeweb or webmock to simulate RestClient::GatewayTimeout in Ruby?

I often see RestClient::GatewayTimeout in my application. I'm trying to figure out how to properly test for this, to make sure my application handles it gracefully.
The closest thing to this that I see is stub_request(:any, 'www.example.net').to_timeout
That raises RestClient::RequestTimeout however and not RestClient::GatewayTimeout. What's the best way to simulate the latter?
stub_request(:any, 'www.example.net').to_raise(RestClient::GatewayTimeout)
This will obviously work only for RestClient and if you change RestClient to
some other library, you'll have to change your test too.

How can I test WebSockets (using Pusher) with RSpec?

I am looking for successful methods for testing WebSocket push events using RSpec. My application currently uses Pusher App, but more broad information relating to WebSockets is most welcome.
Ideally, I'd like something as simple as:
parsed_body = JSON.parse(response.body)
parsed_body["error"].should == "xyzError"
...which I have found to be an awesomely convenient way to test for JSON responses.
Sincere thanks in advance.
Tristan Dunn came out with this awesome gem: https://github.com/tristandunn/pusher-fake
WebSocket server is remote service. It's good way to stub any requests to remote services and mock responses from these ones.

What is the recommended method of testing a JSON client-server api?

Edit #2: Does anyone have a good method of testing the "middle" of a client-server application where we can intercept requests and responses, fake the client or server as needed, and which provides self-documentation of the api?
Cucumber might be a good solution in many cases, but it's not quite what I'm looking for. And this middle layer should be client/server implementation agnostic. (e.g., black-box).
Our client-server model is a ruby-on-rails server with a Flex client, using a RESTish interface with JSON as the data format. So anything the client posts to the server is usually a single JSON parameter. The server does it's thing and responds with a pure JSON model.
We have standard rails testing on the server and we're working on getting proper FlexUnit tests completed on the client (it's a moving target). However, there's a debate in my team about the effectiveness of the current testing model, since every change on the server seems to break part of the API. This is telling me that there is both a problem with API communication (between team members, self-documentation in code, etc..), and a lack of proper API sanity testing.
So I've been questioning whether we need to have a mock client for testing the server at a pure JSON level (without all the other complexities of a rich client), and possibly a mock-server for doing the same thing with the rich client. This would serve two purposes, to document the API and to provide more thorough testing of the API itself.
The reason there's a debate is that the rails guy claims that the rails integration testing is sufficient for testing all the server requests, and the middle-ground testing environment would simply be redundant.
So the question here is, given our situation, how should be go about self-documenting the API, and how should we test the API itself?
EDIT:
We have routes like /foo/444/bar.js, but the parameters can be virtually any complex JSON string depending on the action, e.g.:
json={
"foo":{
"x":1,
"y":2
},
"bar":[1,2,3,4,5]
}
but besides manually-edited API docs, there's no self-documentation. The rails controller often just deserializes and applies changes directly to the model. Would be nice to have common tests to tell us when it's changed, and what's expected.
I just started looking at this web functional testing tool called Maxq and I think it has the potential to solve your problem, Maxq acts as a proxy server between your web client and server application.
It sits on top of Junit so that means you could do proper unit testing for your API by asserting the behavior and responses of calls to your server app.
It basically captures and records all the requests you make from a web client and the responses you get back from a server, it also has the ability to generate test scripts of your request which you could use to play back and test on any server.
You should try it out http://maxq.tigris.org/
You can think of it as two different projects.. if you had two project, you would've writing two separate test suites right?
You should start by establishing the API between the server and the client- as if you wont have any communication between the teams after you start implementhing.
Then you build the client that consume the API and a server that produce the API (or the tests first, if you TDD).
For testing, one team need a mock-server to supply fake API responses to test the client, and the other team need to test the produced data of the server (i.e, the second team is using ails integration testing like your rails guy claims)
I would recommend Cucumber. It allows you to write specific tests for your application by emulating a browser. This way you can send requests and validate the JSON response easily.
One way you can do this is controller tests using rspec (you can also use test::unit)
describe PersonApiController
# GET /person/1.json
it "should respond with a person" do
person = Person.create(:name => "scott")
get :show, :id => person.id, :format => 'json'
response.should be_success
response.body.should have_selector('name', :content => person.name)
end
end

Resources