Stub repeated method calls for rake test - ruby

For my project I use rake test for testing my libs. For example, I've got a method, like connection.users.add_users(options)
json_response = check_users(options)
batch = nil
Timeout::timeout(30) do
begin
sleep 1
batch = connection.batches.find(json_response["batch_id"])
end while batch.state !="completed"
end
connection.users.add_users(batch.target_id, options)
So, first I make an HTTP request to my service, then I get the response (batch_id), loop until the batch is finished, then make another request and return the response.
Usually, in specs I do
let(:connection){setup_test_connection('{"batch_id": 344235}', '202')}
Which will stub connection's response, but in the case of this method it stubs only the first call and then tries to make a real request to my service and so I get an error (timeout because the service is actually down at that time).
Is there any way to stub every possible call of connection's class methods?

So i found out.
I should have used stubs to fake inside requests like this:
connection.servers.stubs(:schedule_create).returns({"batch_id" => 235234})

Related

Test route dispatch

I have an API with a scenario that forwards a request onto another controller.
ie:
$request = Request::create'/new/resource', 'POST');
Route::dispatch($request);
How would I write a test to verify this dispatch happens as I expect? (I know I'm not supposed to mock the 'Request' facade)
ie:
class MyTest extends TestCase {
public function myTestShouldForwardRequestCorrectly()
{
// Once for initial request, and once for fwd request?
// Maybe also test w/ mockery spy which resource the Request is going to?
$m = Route::shouldReceive('dispatch')->times(2);
.... setup test ...
$this->call('POST', '/initial/resource', $parameters);
}
}
You dont have to mock Request - just verify that it is beeing sent. Dispacth will be verified upon controller action. When you call:
$this->call("POST","/path",$params);
You are triggering route collection which act as a lookup table. That collection is storing all predefined routes. So you will have to hook into that collection, to verify your own dispatch. Whole response process ih handled by TTPKernelInterface, and act like a stack - which returns response to user. To test, you will have to do a lot of mocking, because of dependencies. You may take a look at core Laravel tests directory. There you can find how Taylor Otwell tested whole framework without application - by simulating request. I learned a lot from there.

Ruby WebMock: Getting Actual Parameters Passed Through a Method and Using Them in Spec File

I'm using WebMock to stub out HTTP requests. I have this one particular call where, instead of creating dummy data to pass through, I want to be able to capture the actual parameters I would pass into my send() method. Therefore, I need access to those actual parameters in my spec and I imagine I would need to somehow capture that context.
So, for example, in my application I'm calling this method:
send(method, uri, :body => data_file)
And in my spec file I'm stubbing the method:
FoobarModule.should_receive(:send).with(args)
Is there any way I could -- in WebMock, Rspec -- get the context of when send() is being called in the application and grab those parameters I'm passing through to use them within the spec and replace them with args?
I've looked through the documentation and I don't see much of anything on this. If there's anyone aware of this, I would greatly appreciate your help. Thanks.
Using WebMock you could use request callbacks to capture request data:
WebMock.allow_net_connect!
WebMock.after_request do |request_signature, response|
puts request_signature
end

Ruby Sinatra: Can I update a view template multiple times within one client request

I want to do this:
get '/test' do
#dog = 'WOOF'
erb :test
sleep(1)
#dog = 'BOWWOW'
erb :test
sleep(1)
#dog = 'ARF'
erb :test
end
Is it possible to do something like this where the client sees each update or no, I've tried but can't get it to work.
In short: no.
I think you're confusing the way HTTP works. First, HTTP is stateless. This means that multiple requests know nothing about each other (this is mitigated by the use of sessions via cookies, or possibly HTTP basic auth).
Further, you cannot resend the HTTP body like you're doing. Once it's sent there's no going back. Techniques like long-polling delay sending the body so they can send it whenever they like, but once they send something the request is complete and a new one must be started. Thus, once you've rendered the body once via erb, you're request is finished.
What it seems like you're trying to achieve can only be done via Javascript with AJAX, or with completely separate full-page requests.

How can I block on an EventMachine deferrable object?

I'm making a request to another server as part of a POST method to my Sinatra application. The library I'm using to make the request is an EventMachine library that immediately returns an EM::Deferrable object when a request is made, but I need to block in the controller method until the asynchronous request completes so I can return a partial with data returned in the request. What's the best approach for doing this?
One solution would be to use async_sinatra and an EM based webserver like Thin. With async_sinatra you would have a body method for explicit rendering. It would work like this:
require 'sinatra/async'
require 'em-http-request'
class Application < Sinatra::Base
register Sinatra::Async
apost '/' do
http = EM::HttpRequest.new('http://www.google.de/').get
http.callback do
body do
# your http processing in here, will be rendered
end
end
http.errback do
body { 'error' }
end
end
end
When you block on an evented API, you get worst of the two worlds.
I would try to avoid calls through EM in favor of more 'traditional' methods (a-la curl).
If this is not possible, then I would return an empty partial and have client poll the server for updates.

How to get synchronous HTTP response?

I write a class to handle the request to web. And it has a method which is using WebClient actually to do the main job. When the DownloadStringCompleted method has been done, I want to return the value of the response.
I want to use that like this:
// the pubTimeLine() method returns the value
// of the request to the web using WebClient
textBlock1.DataContext = wp.pubTimeLine(url);
How to make it? Or how to get the synchronous response of HTTP request?
You should never make synchronous network calls, it will freeze up your UI (and therefore your phone) which is a very bad user experience.
Instead do it asynchronously, something like:
wp.pubTimeLine(url, result => textBlock1.DataContext = result);
Where the second parameter is a lambda expression containing the callback that is called when the pubTimeLine method is done executing asynchronously.

Resources