Rails和设计 - 在登录和注销时测试控制器

时间:2016-04-21 10:13:31

标签: ruby-on-rails ruby rspec devise

所以我想测试使用设计的控制器。

require 'rails_helper'

describe ArticlesController do
  before(:all) { @article = FactoryGirl.create(:article) }

  sign_in_admin

  describe 'GET new' do
    let(:call_request) { get :new }

    before { call_request }

    context 'admin signed in' do
      it { is_expected.to respond_with :ok }
    end

    context 'admin signed out' do
      it { is_expected.to respond_with 302 }
    end
  end
end

我跟着this guide from devise wiki。所以我创建了ControllerMacros模块,如下所示:

module ControllerMacros
  def sign_in_admin
    before(:each) do
      @request.env['devise.mapping'] = Devise.mappings[:admin]
      @admin = FactoryGirl.create(:admin)
      sign_in @admin
    end
  end
end

并将其包含在rails_helper中以及其他所需的内容中:

require_relative 'support/controller_macros.rb'

RSpec.configure do |config|
  config.include Devise::TestHelpers, type: :controller
  config.extend ControllerMacros, type: :controller
(...)

这是admin factory:

FactoryGirl.define do
  factory :admin do
    email 'email@email.com'
    password 'password'
  end
end

但现在我不知道如何退出管理员?由于sign_in_admin在每次测试之前执行,但是我需要为某些测试签署admin。使用登录/注销管理员测试此控制器的最佳方法是什么?

顺便说一下,我对测试有点新鲜了

2 个答案:

答案 0 :(得分:1)

Devise提供了一些帮助方法进行测试,包括带用户的login_user,因此您不需要创建sign_in_admin函数。此外,通过使用块顶部的before(:all),您已经登录了整个规范套件的管理员。

在您想要signed_in_admin的各个上下文中使用before(:each)。

describe ArticlesController do
  describe 'GET new' do
    let(:call_request) { get :new }
    let(:admin_user) { FactoryGirl.create(:admin) }

    before { call_request }

    context 'admin signed in' do
      sign_in(admin_user)
      it { is_expected.to respond_with :ok }
    end

    context 'admin not signed in' do
      it { is_expected.to respond_with 302 }
    end
  end
end

答案 1 :(得分:0)

更好的方法是将before动作关闭到上下文中。上下文为 signed_in 。所以你可以做如下的事情:

  describe 'GET new' do
    let(:call_request) { get :new }

    before { call_request }

    context "signed in" do
      before { sign_in_admin }

      it { is_expected.to respond_with :ok }
    end

    context 'non-singed in' do
      it { is_expected.to respond_with 302 }
    end
  end