How to test simple rake application - ruby-on-rails

i am using grape for creating rest api i created the api and its working fine now i have to test this api.when we create rails api there is automatically spec_helper.rb file is generated now as usual first line for testing is
require spec_helper
please tell what should be the code for spec_helper.rb file
and other things i should focus when testing a simple rake application.i am giving a small code snippet for example i have to test
require 'grape'
require 'sequel'
require 'json'
module Twitter
class API < Grape::API
version 'v1', :using => :header, :vendor => 'twitter'
format :json
helpers do
def current_user
#current_user ||= User.authorize!(env)
end
def authenticate!
error!('401 Unauthorized', 401) unless current_user
end
end
resource :users do
desc "Return a status."
params do
requires :id, :type => Integer, :desc => "Status id."
optional :include , :type => String , :desc =>"parameter to include in "
end
get ':id' do
"Hello World"
end
in this grape application when i call localhost:9292/users/1234
then response should be "Hello World" how to test this app what should be content of spec_helper.rb file for testing.i am using only grape not using rails

It all depends on what you want to test.
Presumably the route you want to test (localhost:9292/users/1234) is a UsersController. That being the case, you will want to do something like this (using rspec):
describe UsersController do
context "GET#show" do
it "should return 'Hello World'" do
get :show, id: 1234
response.body.should include 'Hello World'
end
end
end
Now as for the rake task test, I would create an integration test that executes the rake task from the command-line and compares expected results to the output of the rake task sort of like this:
describe "My Rake Task" do
it "should return hello world" do
results = `bundle exec rake my:rake:task`
results.should include 'Hello World'
end
end
Hope these rough examples work for you! Good luck!
UPDATE:
You should always write unit test on classes as much as possible so your rake task tests are very simple or not even needed.

I think you mean Rack app. There's a pretty decent section on testing in the README for Grape. You should start there.
https://github.com/intridea/grape#writing-tests

Related

how to confirm if the object was deleted in rails-for-API?

I created a destroy method and now I wanted to know how I can test and render if the object manages to be removed or not.
def destroy
if #syllabus.destroy
render :no_content
else
end
end
I think you are looking for something like rspec-rails,
after following the installation instructions on the gem repository you can generate a testing file with:
bundle exec rails generate rspec:controller my_controller
this would generate a file like the following:
# spec/controllers/my_controller_spec.rb
require 'rails_helper'
RSpec.describe MyControllerController, type: :controller do
# your code goes here...
end
then you can add a test example like this one:
# spec/controllers/my_controller_spec.rb
require 'rails_helper'
RSpec.describe MyControllerController, type: :controller do
#replace attr1 and attr2 with your own attributes
let(:syllabus) { Syllabus.create(attr1: 'foo', attr2: 'bar') }
it 'removes syllabus from table' do
expect { delete :destroy, id: syllabus.id }.to change { Syllabus.count }.by(-1)
end
end
** the code above is not test and it was made just as a guide **
for you destroy action method it's ok but, you could improve it a bit if you leave it like:
def destroy
#syllabus.destroy
end
this is because your if/else condition is not doing much on the method and rails by default should respond with a 204 no content

What is the proper way to test a Rails controller's action that is using throw :async?

I have a Rails server running on Thin and an async controller action. I would like to test it using RSpec, but I am getting an error:
Failure/Error: get :access_token
ArgumentError:
uncaught throw :async
This is a sample code:
class SampleController < ApplicationController
def sample
EM.defer do
render json: { response: 'Hello World' }
request.env['async.callback'].call response
end
throw :async
end
end
require 'spec_helper'
describe SampleController, :type => :controller do
it "hello world" do
get :sample
expect(JSON.parse(response.body)[response]).to eq('Hello World')
end
end
The reason why I get this error is because :async can only be handled by Thin server. There is no Thin server available in a vanilla Rails controller.
So tried Capybara:
describe "GET /sample", type: feature do
it "hello world" do
visit sample_path
expect(JSON.parse(page.body)['response']).to eq('Hello World')
end
end
# In spec_helper.rb
Capybara.server do |app, port|
require 'rack/handler/thin'
Rack::Handler::Thin.run(app, :Port => port)
end
But I still get the same error. I believe it is because Thin needs to be started in threaded mode; and capybara does no start it in such a way.
What is the proper way to test a controller's action that is using throw :async?
The action does work when I use a regular browser to get to it.
In order to test an asynchronous Ruby on Rails action implemented with Thin you will need to run the test using Thin. Otherwise it will fail, or be brittle – in case you try mocking things up.
So let's set it up using Capybara:
In Gemfile:
gem 'thin'
gem 'capybara'
gem 'selenium-webdriver'
In spec/rails_helper.rb:
require 'capybara/rails'
Capybara.default_driver = :selenium
Capybara.server do |app, port|
require 'rack/handler/thin'
Rack::Handler::Thin.run(app, :Port => port)
end
That sets the Capybara driver to be selenium, a real browser. The second part configures the Capybara server to be Thin.
The test should be written then as this:
describe SampleController, :type => :feature do
it "my test" do
visit sample_path
expect(page).to have_content('Hello World')
end
end
And this will make the test pass.
In your RSpec controller test, try replacing
get :sample
with
expect { get :sample }.to throw_symbol(:async)
That should catch it and prevent the spec from failing. It also tests that the controller is async!

Rails route without controller

In my routes file, I have this random route without a controller
match "/ping" => lambda{ |env| [200, {'Content-Type' => 'text/plain'}, ['ACK']] }
Using Test::Unit / MiniTest, how would I go about testing, that yes the route /ping return 'ACK'
When you create a route without a controller, you cannot use ActionController::TestCase to test it. Instead, you should use ActionDispatch::IntegrationTest. Create a file at test/integration/ping_test.rb that includes the following:
require "test_helper"
class PingTest < ActionDispatch::IntegrationTest
def test_ping
get "/ping"
assert_response :success
assert_equal "ACK", response.body
end
end
Definitely using integration tests. See details here: http://guides.rubyonrails.org/testing.html#integration-testing

Failure of functional test for 'create' using should_redirect_to

I have a problem trying to use 'shoulda' with 'factory_girl' for creating a functional test for 'create' in a Rails application. I created a simple project, scaffolded user, added 'shoulda' (current gem version on my system 2.11.3 ) and 'factory_girl' in test_helper.rb. Creating the user manually works fine. Following are the steps to reproduce the failure :
rails project
scaffold user name:string
add in test_helper.rb :
require 'shoulda'
require 'factory_girl'
rake db:migrate
write the following functional test for user (override users_controller_test.rb ) :
class UsersControllerTest < ActionController::TestCase
Factory.define(:user) do |u|
u.name 'joe'
end
context "should create user" do
context "with valid data" do
setup do
User.any_instance.expects(:save).returns(true).once
User.any_instance.stubs(:id).returns(1001)
post :create, :user => {}
end
should_assign_to :user, :class => User
should_set_the_flash_to "User was successfully created."
should_redirect_to("user page"){user_path(1001)}
end
end
end
Running the test with "rake test:functionals" shows failure :
Expected response to be a redirect to <http://test.host/users/1001> but was
a redirect to <http://test.host/users>.
I played also with "should redirect_to", because I saw "should_redirect_to" is deprecated,
but with no luck. Do you have any ideas ?
Thank you in advance,
Marian Vasile Caraiman.
Instead of stubbing User#id, stub User.create and use particular user mock object.
setup do
mock_user = Factory.stub(:user, :id => 1001)
User.expects(:create).returns(mock_user)
mock_user.expects(:save).returns(true)
post :create, :user => {}
end

Test (with RSpec) a controller outside of a Rails environment

I'm creating a gem that will generate a controller for the Rails app that will use it. It's been a trial and error process for me when trying to test a controller. When testing models, it's been pretty easy, but when testing controllers, ActionController::TestUnit is not included (as described here). I've tried requiring it, and all similar sounding stuff in Rails but it hasn't worked.
What would I need to require in the spec_helper to get the test to work?
Thanks!
Here's an example of a working standalone Test::Unit test with a simple controller under test included.. Maybe there's some parts here that you need to transfer over to your rspec code.
require 'rubygems'
require 'test/unit'
require 'active_support'
require 'active_support/test_case'
require 'action_controller'
require 'action_controller/test_process'
class UnderTestController < ActionController::Base
def index
render :text => 'OK'
end
end
ActionController::Routing::Routes.draw {|map| map.resources :under_test }
class MyTest < ActionController::TestCase
def setup
#controller = UnderTestController.new
#request = ActionController::TestRequest.new
#response = ActionController::TestResponse.new
end
test "should succeed" do
get :index
assert_response :success
end
end

Resources