我有一个员工模型,客户端模型和一个Office模型。 Devise正在控制Employee上的身份验证逻辑。我有多个控制器,它们是一个基础控制器的子类,它设置了所有控制器(DRY)所需的一切。在测试这些控制器时,我需要能够在已签名的设备员工中模拟退回的办公室,以便控制器测试正常运行,但是我遇到了问题。
以下是描述我的问题所需的所有代码。 应用/模型/ employee.rb
class Employee < ActiveRecord::Base
devise :database_authenticatable, :token_authenticatable, :recoverable, :rememberable, :trackable, :validatable, :lockable, :timeoutable
attr_accessible :username, :password_confirmation, :password, :email, :office_id
belongs_to :office
end
应用/模型/ client.rb
class Client < ActiveRecord::Base
belongs_to :office
end
应用/模型/ office.rb
class Office < ActiveRecord::Base
has_many :employees
has_many :clients
end
配置/ routes.rb中
Project::Application.routes.draw do
devise_for :employees
namespace :employees do
resources :clients
end
end
应用/控制器/雇员/ base_controller.rb
class Employees::BaseController < ApplicationController
before_filter :authenticate_employee! && :set_office
private
def set_office
@office = current_employee.office
end
end
应用/控制器/雇员/ clients_controller.rb
class Employees::ClientsController < Employees::BaseController
def create
flash[:notice] = Message::SOME_MESSAGE
end
end
规格/支持/ controller_macros.rb
module ControllerMacros
def login_employee
let(:current_employee) { Factory(:employee) }
let(:mock_office) { mock_model Office }
before(:each) do
@request.env["devise.mapping"] = Devise.mappings[:employee]
sign_in :current_employee, current_employee
current_employee.should_receive(:office).and_return(:mock_office)
end
end
end
规格/ spec_helper.rb
require 'rubygems'
require 'spork'
Spork.prefork do
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
config.mock_with :rspec
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = true
config.include Devise::TestHelpers, :type => :controller
config.extend ControllerMacros, :type => :controller
end
end
Spork.each_run do
end
规格/控制器/雇员/ clients_controller_spec.rb
require 'spec_helper'
describe Users::ClientsController do
login_employee
it { should inherit_from(Users::Admin::BaseController) }
describe 'basic test' do
before do
post :create, {}
end
it {should respond_with_content_type(:html)}
end
end
运行规范的结果
(in /Users/developer/Development/Workspace/Project.ror3) /Users/developer/.rvm/rubies/ruby-1.9.2-p180/bin/ruby -S bundle exec rspec ./spec/controllers/employees/clients_controller_spec.rb No DRb server is running. Running in local process instead ... .F Failures: 1) Users::ClientsController basic test Failure/Error: post :create, {} NoMethodError: undefined method `office' for nil:NilClass # ./app/controllers/employees/base_controller.rb:6:in `set_office' # ./spec/controllers/employees/clients_controller_spec.rb:12:in `block (3 levels) in ' Finished in 1.09 seconds 2 examples, 1 failure Failed examples: rspec ./spec/controllers/employees/clients_controller_spec.rb:15 # Users::ClientsController basic test rake aborted! ruby -S bundle exec rspec ./spec/controllers/employees/clients_controller_spec.rb failed (See full trace by running task with --trace)
注意:有很多代码减肥以获取上述所有信息。我多次重读并认为问题不在设置中,而是设计对象本身(使用sign_in)。如果您需要更多,请索取。
答案 0 :(得分:2)
module ControllerMacros
def login_employee
let(:current_employee) { mock_model Employee }
let(:mock_office) { mock_model Office }
before(:each) do
request.env['warden'] = mock(Warden, :authenticate => current_employee,
:authenticate! => current_employee)
current_employee.should_receive(:office).and_return(:mock_office)
end
end
end