Stub requests in capybara rspec - ruby-on-rails

I am writing a feature rspec(capybara) which uses stub request. I am stubbing the request in capybara but getting an error that body is different. When I checked, the port number is changing everytime a request is made.
http://127.0.0.1:44949/v2
how to fix the port number everytime a new request is made or any other way to solve this issue ?

Related

Mocking login for remote services - Cucumber, Capybara, Rails

I have a Rails application that has changed from user authentication via devise to accessing a remote API for authentication. For the test suite, this requires that I mock the https request for authentication and return a valid response. We are using Cucumber and Capybara for testing and I am attempting to use the webmock Gem to mock the login response.
The login is initiated by a button click on a form (Capybara action 'click_button').
Unfortunately, although webmock appears to be installed correctly (I am able to make a Net::HTTP POST request and this is recognized by Webmock), the POST to the remote authorization facility is not being captured by webmock. I know that the form POST is making its way to the controller, because the stacktrace shows that the POST is being executed in the controller as it should and the error message is "Errno::ECONNREFUSED at ... Failed to open TCP connection".
I have tried:
WebMock.stub_request(:any, '127.0.0.1').to_return(body: {STATUSCODE: 1}.to_json)
and
WebMock::stub_request(:any, '127.0.0.1').to_return(body: {STATUSCODE: 1}.to_json)
and
stub_request(:any, '127.0.0.1').to_return(body: {STATUSCODE: 1}.to_json)
I have tried putting the stub_request call in the devise_steps.rb file, just before the "click_button" command, as well as in the features/support/env.rb and features/support/webmock.rb file.
I assume that what I am doing is so common that it has to be possible, but I have found nothing that indicates why the stub_request is not successful.
So the domain of the remote API for authentication is localhost? So it would be running on the same server with a different port? Then you have to mock the address with the port.
For instance your Rails app is running on port 80 and your auth API is running on 8080 then you have to do this.
stub_request(:any, '127.0.0.1:8080').to_return(body: {STATUSCODE: 1}.to_json)
I think Webmock should support different ports but I'm not 100% sure. Also have you set WebMock.disable_net_connect!(allow_localhost: true)?
https://github.com/bblimke/webmock#external-requests-can-be-disabled-while-allowing-localhost
Edit:
If this is not working, I suggest you make the API URL configurable and e.g. set it in tests to auth-api.com and then mock this.
The root cause of the problem was that the path on the stub_request was not complete. I had misread the webmock documentation....

How to mock a request in ruby on rails

How to mock a request in ruby on rails
I am making a call to multiple external sites via API and facing lot of failures in the response due to net read timeout error and parameters errror , run time errors, etc.
I want to mock the request before making a original call to the API. So that i can avoid more failures in my app.
Can any one help me ?
Try using the VCR gem, it records HTTP request for you, the first time you run your tests. For subsequent tests VCR uses the previously recorded HTTP response.
This should solve your timeout errors and allow you to work with external API's more easily.
Checkout these resources for more info:
https://www.relishapp.com/vcr/vcr/docs
http://natashatherobot.com/vcr-gem-rails-rspec/

How to fail a cucumber scenario when rails app returns internal server error?

The tech stack that we use for functional tests is cucumber with stubby4j for stubbing requests. Sometimes if there is no stub found for a request, rails throws "internal server error" but our functional tests passes in some cases.
Requirement is:
When any call made in rails app returns HTTP error code say 500, I want my cucumber scenario to fail. Is there any way to do this?

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.

Integration tests of web services and XHR

I am using Steak and Capybara to do my integration tests. I also would like to test the serialization output (webservices using XML and JSON format) of my models. The problem is that JSON is only available by using a XML HTTP Request. So Capybara's visit method does not work. It also seems that I don't have access to xhr method in my acceptance tests (not sure why, because I require the normal spec_helper.rb in my acceptance_helper.rb).
How do you test web services? Using the xhr method (after requiring it somehow)? A special method with Capybara? Something else?
I also have some custom serialization (beside the normal my_object.to_xml). I guess it is better to do that in the model tests. Would you then still test the web service output of those custom serializations?
You can always create a "proxy" controller that makes requests to the web service and prints the result. It should be available only in test environment, obviously. Then your Capybara test visits the proxy and tests page content.

Resources