Estive estudando o Rails 3 (Atualmente 3.0.1 para o rails), e também estudando um pouco de NoSQL, com o MongoDB, ainda pretendo me dedicar um pouco para aprender sobre o Redis, mas por enquanto estou vendo o Rails. Gosto de usar para autenticação o Devise, um projeto brasileiro, que se tornou bem famoso pelo mundo Rails. Para ORM gostei do Mongoid, e ainda mais pelo devise ter suporte ao mongoid ao invez do ActiveRecord.
Iniciando
Sobre o mongoid não há muito o que falar, a documentação presente no site é completa, e funciona muito bem, vale lembrar que arquitetura de um banco relacional é bem diferente de um NoSQL, e algumas definições já padrão na nossa cabeça devem ser desfeitas.
O RSpec-Rails vem configurado para rodar sobre o ActiveRecord e quando vc executar um rails g rspec:install ira gerar toda a estrutura padrão do rspec, incluindo a pasta spec que contem os testes. Primeiramente vamos editar o arquivo spec/spec_helper.rb
RSpec.configure do |config| require 'database_cleaner' config.before(:suite) do DatabaseCleaner.strategy = :truncation DatabaseCleaner.orm = "mongoid" end config.before(:each) do DatabaseCleaner.clean end config.mock_with :rspec config.include Devise::TestHelpers, :type => :controller # Essa linha adiciona os helpers do Devise para o RSpec. end
A adição da gem DatabaseCleaner (que deve estar declarada no Gemfile), serve para limpar os resultados dos testes apos a execução, como podem reparar o uso de fixtures é desabilidado para o Mongo, somente para o ActiveRecord, sem o uso de fixtures os testes são mantidos na base, o que não é interessante.
Testando os controllers
Criei um modelo simples com o devise, apesar da documentação do devise indicar a criação de um modelo Admin para esses casos, preferia adotar o uso de um flag para poder indicar se o usuário é um administrador, acho isso um tanto mais simples.
Adicionei também no application_controller.rb um metodo filtro que indica se o usuário é um adminsitrador
protected def admin_user! if authenticate_user! unless current_user.admin flash[:warning] = "Acesso Negado" redirect_to root_url end end endreparem que usei o filtro authenticated_user! que é do devise pra indicar que o usuário está logado no sistema.
meu controller admin_controller.rb
class AdminController < ApplicationController before_filter :admin_user! def index end endé um controller bem simples, mas para garantirmos a segurança do aplicativo, e se algum dia nosso filtro precisar ser ajustado precisamos garantir que o acesso a esse controller seja restrito sempre, e quem alterar deve ter noção da quebra do teste. Em alguns dos meus testes, normalmente em fixtures, eu pego um hash que representa o codigo BCrypt da senha (padrão do Devise), mas como aqui no mongo não tem fixutes, parti pra outro ponto.
require 'spec_helper' describe AdminController do describe "GET 'index'" do def do_action_with_user(admin) @user = User.create!(:name => "Test", :email => "test@test.com", :password => "testet", :password_confirmation => "testet", :admin => admin) sign_in @user get 'index' end #1 it "should not be successful when no user was logged in" do get 'index' flash[:alert].should_not be_nil response.should_not be_success end #2 it "should not be successful when no admin user was logged in" do do_action_with_user(false) flash[:warning].should_not be_nil response.should_not be_success end #3 it "should be successful when admin user was logged in" do do_action_with_user(true) response.should be_success end end endbem simples, um metodo dry pra fazer o registro do usuario e usar o metodo auxiliar do devise para o login (sign_in):
- o teste 1 é um teste para acesso sem login, no caso uma chamada a action index do controller admin sem um usuário logado.
- teste 2 teste para um usuário que não é administrador, repare que testo se o flash esta preenchido
- teste 3 testa a ação de sucesso, no caso o acesso de um usuário administrador
Outras notas
Tive alguns problemas no começo do uso do RSpec 2 em views, e vou listar aqui alguns deles:
assign :name, "Teste"ao invez de
assigns[:name] = "Teste"Outra mudança é que em views você não deve mais usar o response, mas usar o rendered. Também deixou de existir o metodo have_tag, para verificar o conteudo de uma tag, veja abaixo:
#RSpec 3 assert_select('p', "Teste") #RSpec 2 response.have_tag 'p', "Teste"
Espero que isso seja util pra mais alguem, pelo menos eu não vou mais esquecer :D
1 comentários:
Muito útil. Ajudou bastante. Valew!
Postar um comentário