How to test or stub Sidekiq::Batch in RSPEC? - ruby-on-rails

How to test or stub Sidekiq::Batch in RSPEC ?
Please see got error in code below.
rails_helper
require 'spec_helper'
require File.expand_path('../../config/environment', __FILE__)
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'
require 'sidekiq/testing'
Sidekiq::Testing.fake!
Worker to be tested...
class TestWorker
def perform(id)
batch = Sidekiq::Batch.new
batch.description = "Sample"
batch.on(:complete, TestWorker, 'id' => 123, 'last_checked' => Time.now)
# => *** NoMethodError Exception: undefined method `on' for #<Batch:0x007fd8b728a1d0>
batch.jobs do # => NoMethodError: undefined method `jobs' for #<Batch:0x007f936c9ebf68>
Sidekiq::Client.push({
'class' => TestWorker,
'queue' => q,
'args' => [id, batch.bid, 1, Time.now]
})
end
end
end
class TestWorkerCallbacks
def complete(status, options)
#simple record update here
end
end
spec/workers/test_worker_spec.rb
require 'rails_helper'
RSpec.describe TestWorker, type: :worker do
context "Sidekiq Worker" do
it "should respond to #perform" do
expect(TestWorker.new).to respond_to(:perform)
end
describe "perform" do
before do
Sidekiq::Worker.clear_all
end
it "updates order records" do
expect(TestWorker.jobs.size).to eq(0)
TestWorker.perform_async(123)
TestWorker.drain
expect(TestWorker.jobs.size).to eq(1)
end
end
end
end

Related

Using Devise in rspec feature tests

I've written the following rspec feature test spec:
require "rails_helper"
RSpec.describe "Team management", type: :feature do
user_sign_in
describe "User creates a new team" do
...
expect(page).to have_link("#{team_name}")
end
end
The user_sign_in method is defined in my rails_helper.rb:
ENV['RAILS_ENV'] ||= 'test'
require 'spec_helper'
require File.expand_path('../../config/environment', __FILE__)
require 'rspec/rails'
require 'capybara/rails'
...
module UserSignInHelpers
def user_sign_in
before(:each) do
#request.env['devise.mapping'] = Devise.mappings[:user]
#current_user = FactoryGirl.create(:user)
#current_user.confirm
sign_in :user, #current_user
end
end
end
RSpec.configure do |config|
...
# The different available types are documented in the features, such as in
# https://relishapp.com/rspec/rspec-rails/docs
config.infer_spec_type_from_file_location!
config.extend UserSignInHelpers, type: :controller
config.extend UserSignInHelpers, type: :feature
config.include Devise::TestHelpers, type: :controller
config.include Devise::TestHelpers, type: :feature
end
The user_sign_in method works from all of my controller specs but when I run my feature spec it fails with:
Team management
User creates a new team
example at ./spec/features/user_creates_a_new_team_spec.rb:19 (FAILED - 1)
Failures:
1) Team management User creates a new team
Failure/Error: Unable to find matching line from backtrace
NoMethodError:
undefined method `env' for nil:NilClass
# /Users/xxxx/.rvm/gems/ruby-2.2.1/gems/devise-3.5.1/lib/devise/test_helpers.rb:24:in `setup_controller_for_warden'
I don't understand why this works in controller tests and not feature tests. Is there something I can do make this work in feature tests?
There is a basic problem with what you are trying to do. (Devise work on top of Warden)Warden is a
Rack middleware, but RSpec controller specs don't even include Rack,
as these types of specs are not meant to run your full application
stack, but only your controller code.
Ref
Test with Capybara
I have a simple support helper, that allows me to login and logout users:
module Auth
def create_user!
#user = User.create(email: 'foo#bar.com', password: '11111111')
end
def sign_in_user!
setup_devise_mapping!
sign_in #user
end
def sign_out_user!
setup_devise_mapping!
sign_out #user
end
def setup_devise_mapping!
#request.env["devise.mapping"] = Devise.mappings[:user]
end
def login_with_warden!
login_as(#user, scope: :user)
end
def logout_with_warden!
logout(:user)
end
def login_and_logout_with_devise
sign_in_user!
yield
sign_out_user!
end
def login_and_logout_with_warden
Warden.test_mode!
login_with_warden!
yield
logout_with_warden!
Warden.test_reset!
end
end
in a feature:
RSpec.describe "Team management", type: :feature do
describe "User creates a new team" do
login_and_logout_with_warden do
# tests goes here
end
end
end
in a controller:
RSpec.describe "Team management", type: :controller do
describe "User creates a new team" do
login_and_logout_with_devise do
# tests goes here
end
end
end

Rspec controller can't call the action of real controller

i'm using rails 4.1.1 and rspec 3.0.3.
here is the rspec code.
require 'rails_helper'
describe MembersController, type: :controller do
describe 'GET index' do
it 'should be success' do
puts "11111"
get :index
puts "33333"
expect(response).to render_template :index
end
end
end
and :index action of controller is,
def index
puts "22222"
#members = Member.order('mem_id DESC').paginate(page: params[:page]||1, per_page: params[:per_page]||30)
end
==============================
and i did 'rake spec', i exepcted the console to print like this.
11111
22222
33333
but the result is,
11111
33333
and it makes an error message like this.
Failure/Error: expect(response).to render_template :index
expecting <"index"> but rendering with <[]>
what's wrong with my rspec?
----------------------------------- UPDATE QUESTION ------------------------------
this is the spec/rails_helper.rb (all comments are removed)
ENV["RAILS_ENV"] ||= 'test'
require 'spec_helper'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = false
config.infer_spec_type_from_file_location!
end

rails rake test, url helpers not working

Getting the following when running my capybara rails tests with "rake test". Problem seems to be url helpers I'm using in my application.html.erb:
DashboardLoginTest#test_login_and_check_dashboard:
ActionView::Template::Error: arguments passed to url_for can't be handled. Please require routes or provide your own implementation
app/views/layouts/application.html.erb:29:in `_app_views_layouts_application_html_erb__938277815294620636_4045700'
test/integration/dashboard_login_test.rb:6:in `block in <class:DashboardLoginTest>'
Here's line 29 in application.html.erb that its complaining about:
<%= link_to("asdf", root_path, {:class => 'brand'}) %>
Here's what the test looks like:
test "login and check dashboard" do
visit("/")
assert page.has_content?("welcome")
end
Here's my test_helper.rb:
ENV["RAILS_ENV"] ||= "test"
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
require 'factory_girl'
require 'capybara/rails'
include Warden::Test::Helpers
Warden.test_mode!
def main_app
Rails.application.class.routes.url_helpers
end
class ActiveSupport::TestCase
ActiveRecord::Migration.check_pending!
fixtures :all
end
class ActionDispatch::IntegrationTest
# Make the Capybara DSL available in all integration tests
include Capybara::DSL
include Rails.application.routes.url_helpers
def sign_in(user = nil)
if user.nil?
user = FactoryGirl.create(:user)
$current_user = user
end
login_as(user, :scope => :user)
user.confirmed_at = Time.now
user.save
end
end

testing controller with spec and factory girl, can't sign_in

I'm newbie on rails and testing rails applications. I try to test an existing rails application with rspec. I've just finished model tests and i have to complete controller tests too.But i have a problem with sign_in method on rspec. I've tried all solution methods on the internet but still i can't sign in like a user with rspec.
here is the my controller code, it's too simple;
class AboutController < ApplicationController
def index
end
def how_it_works
end
def what_is
end
def creative_tips
end
def brand_tips
end
def we_are
end
def faq
end
end
and here is the my spec code;
require 'spec_helper'
describe AboutController do
before(:all) do
#customer=Factory.create(:customer)
sign_in #customer
end
context 'index page :' do
it 'should be loaded successfully' do
response.should be_success
end
end
end
Here is the my factory code;
Factory.define :unconfirmed_user, :class => User do |u|
u.sequence(:user_name) {|n| "user_#{n}"}
u.sequence(:email){|n| "user__#{n}#example.com"}
u.sequence(:confirmation_token){|n| "confirm_#{n}"}
u.sequence(:reset_password_token){|n| "password_#{n}"}
u.password '123456'
u.password_confirmation '123456'
u.user_type :nil
end
Factory.define :user, :parent => :unconfirmed_user do |u|
u.confirmed_at '1-1-2010'
u.confirmation_sent_at '1-1-2010'
end
Factory.define :customer, :parent => :user do |u|
u.user_type :customer
end
Finally here is the my spec_helper code
ENV["RAILS_ENV"] ||= 'test'
require File.dirname(__FILE__) + "/../config/environment" unless defined?(Rails)
require 'rspec/rails'
require "paperclip/matchers"
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
RSpec.configure do |config|
config.include Paperclip::Shoulda::Matchers
end
RSpec.configure do |config|
config.include Devise::TestHelpers, :type => :controller
end
RSpec.configure do |config|
config.mock_with :rspec
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
end
gem file;
gem 'rails', '3.0.3'
gem 'mysql2', '< 0.3'
.
.
.
gem "devise" , "1.1.5"
.
.
.
group :test do
gem 'shoulda'
gem "rspec-rails", "~> 2.11.0"
gem "factory_girl_rails"
end
and here is the error;
Failures:
1) AboutController index page : should be loaded successfully
Failure/Error: sign_in #customer
NoMethodError:
undefined method `env' for nil:NilClass
# ./spec/controllers/about_controller_spec.rb:7:in `block (2 levels) in <top (required)>'
solution must be too easy but I'm newbie on rails and i can't find it :(
You have to make the sign-in step inside the it block in order for rspec to be able to access the response, e.g.:
it 'should be loaded successfully' do
sign_in #customer
response.should be_success
end
You have no subject.
require 'spec_helper'
describe AboutController do
before(:all) do
#customer=Factory.create(:customer)
sign_in #customer
end
context 'index page :' do
subject { Page }
it 'should be loaded successfully' do
response.should be_success
end
end
end
You might need to visit customers_path.

ControllerMacros cannot be seen in RSpec

I have a Rails app and I am trying to test it. I use devise to log in. However, I faced a problem that occurs when I want to test:
Users/ender/Projects/ratingw/spec/controllers/widgets_controller_spec.rb:4:in `block in <top (required)>': undefined local variable or method `login_user' for #<Class:0x007fe909bd5070> (NameError)
First, I want to say that I read this devise formal tutorial.
My spec_helper.rb is:
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/rspec'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
# ## Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
OmniAuth.config.test_mode = true
OmniAuth.config.mock_auth[:twitter] = {
:provider => 'twitter',
:uid => '123545'
# etc.
}
OmniAuth.config.mock_auth[:twitter] = :invalid_credentials
config.include Devise::TestHelpers, :type => :controller
config.extend ControllerMacros, :type => :controller
config.include RequestMacros, :type => :request
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
end
module ::RSpec::Core
class ExampleGroup
include Capybara::DSL
include Capybara::RSpecMatchers
end
end
and also I have a controller_macros.rb, which is located in support file:
module ControllerMacros
def login_user
before(:each) do
#request.env["devise.mapping"] = Devise.mappings[:user]
user = Factory(:user)
#user.confirm! # or set a confirmed_at inside the factory. Only necessary if you are using the confirmable module
sign_in user
end
end
end
and finally, my controller_spec file is:
require 'spec_helper'
describe WidgetsController do
login_user
describe "User" do
before(:each) do
#current_user = mock_model(User, :id => 1)
#widget = mock_model(Widget, :user_id => 1)
Widget.stub!(:current_user).and_return(#current_user)
Widget.stub!(:widgets).and_return(#widget)
end
it "should have a current_user" do
subject.current_user.should_not be_nil
redirect_to widgets_path
end
it "should not have a current_user" do
redirect_to widgets_path new_user_session_path
end
end
def mock_widget(stubs={})
#mock_widget ||= mock_model(Widget, stubs).as_null_object
end
describe "Get index" do
it "should get all widgets " do
Widget.stub(:all) { [mock_widget] }
get :index
assigns(:widgets) == #widgets
end
end
describe "Post widget" do
it "creates a new widget" do
Widget.stub(:new).with({'these' => 'params'}) { mock_widget(:save => true) }
post :create, :widget => {'these' => 'params'}
assigns(:widget) == #widgets
response.should redirect_to (edit_widget_path(#mock_widget))
end
it "can not create a new widget" do
Widget.stub(:new).with({'these' => 'params'}) { mock_widget(:save => false) }
post :create, :widget => {'these' => 'params'}
assigns(:widget) == #widgets
redirect_to new_widget_path
end
end
describe "Get widget" do
it "shows exact widget via its uuid" do
Widget.stub(:find).with("10") { mock_widget(:save => true) }
get :show
assigns(:widget) == #widget
end
end
describe "Put widget" do
it "updates the widget attributes" do
Widget.stub(:find_by_uuid).with("6").and_return(mock_widget(:update_attributes => true))
mock_widget.should_receive(:update_attributes).with({'these' => 'params'})
put :update, :uuid => "6", :widget => {'these' => 'params'}
response.should redirect_to (edit_widget_path(#mock_widget))
end
it "can not update the widget attributes" do
Widget.stub(:find_by_uuid).with("6").and_return(mock_widget(:update_attributes => false))
mock_widget.should_receive(:update_attributes).with({'these' => 'params'})
put :update, :uuid => "6", :widget => {'these' => 'params'}
end
end
describe "delete destroy" do
it "destroys the requested widget" do
Widget.stub(:find_by_uuid).with("10").and_return(mock_widget)
mock_widget.should_receive(:destroy)
get :destroy, :uuid => "10"
end
end
end
How can I fix this? What is the problem?
I guess the error stems from:
config.extend ControllerMacros, :type => :controller
You should have:
config.include ControllerMacros, :type => :controller

Resources