2012年3月3日土曜日

rspecでruby on rails3(devise)のcontrollerをいい感じに書いてみた~part2


前回の投稿の続きであるが、
さらに、GETアクションに加え、CREATE・UPDATEアクションも考慮して汎用ロジックを組んでみました。

前回のエントリも参考にしていだだきたい。
[ rspecでruby on rails3(devise)のcontrollerをいい感じに書いてみた~part1 ]

【環境】
devise'2.0.4'
rails'3.1.3'
rspec-rails'2.8.0'

【テスト概要】

アクションごとに

ログインしている場合
・取得オブジェクトが参照できる

:renderingを期待している場合
  ・responseが200[OK]である
  ・正しいtemplateをレンダーする
:redrectを期待している場合
   ・正しいリダイレクト先へいく

ログインしてない場合
   ・取得オブジェクトが参照できない
   ・正しいリダイレクト先へいく

をテストすることを想定。








describe BlogsController do

  before(:each) do
    @crtl = described_class.to_s.downcase
    @crtl_head = @crtl.split(/controller/)[0]

 
    def do_req(req,action,params)
      case req
        when "get" then
          get action, params
        when "post" then
          post action, params
        when "put" then
          put action, params
        when "delete" then
          delete action, params
      end
    end
  end

  describe "#login_user" do
    login_user    
    it { subject.current_user.should be }
  end

  shared_context "Do_Reqest" do |req,action,params,expects,objs,result,template,rto_path|
    before do
        @len = 2
        @len = @len- 1 if action == :index    
        @obj = @crtl_head[0..@crtl_head.length-@len]
    end

    context "in logined_user" do
      login_user
      before { do_req(req,action,params) }
       
      if objs.nil?
        it { assigns(@obj.to_sym).should be ,"assigns(#{@obj.to_sym})"}
      else
        objs.each do |obj|
          it { assigns(obj).should be , "assigns(#{obj})" }
        end
      end

      case result
        when "true" then
          it { assigns(:result).should be_true , ":result=>#{assigns(:result)}"}
        when "false" then
          it { assigns(:result).should_not be_nil }
          it { assigns(:result).should be_false , ":result=>#{assigns(:result)}"}
      end

      case expects
        when "render" then
          it { response.should be_success }
          subject { response }
            it { should render_template("layouts/#{@crtl_head}") }
            it "render template" do
              template = @crtl_head + "/" + action.to_s.delete(":") if template == nil
              should render_template(template), "template=>#{template}"
            end
        when "redirect" then
          if rto_path == nil
            it { subject.response.should redirect_to(blog_path(assigns(:blog))),"redirect_to=>#{blog_path(assigns(:blog))}" }          
          else
            it { subject.response.should redirect_to(eval(rto_path)), "rto_path=>#{rto_path}"}
          end
      end
 
    end
 
    context "in no_logined_user" do
      before { do_req(req,action,params) }

      it { subject.current_user.should be_nil }

      if objs.nil?
        it { assigns(@obj.to_sym).should be_nil ,"assigns(#{@obj.to_sym})"}
      else
        objs.each do |obj|
          it { assigns(obj).should be_nil , "assigns(#{obj})" }
        end
      end
      it { response.should redirect_to(user_session_path) }    
    end
  end


  describe "#index" do
    include_context "Do_Reqest","get",:index
  end

  describe "#new" do
    include_context "Do_Reqest","get",:new
  end

  describe "#show" do
    @blog = Factory.build(:blogc)
    include_context "Do_Reqest","get",:show,id: @blog.to_param
  end

  describe "#edit" do
    @blog = Factory.build(:blogc)
    include_context "Do_Reqest","get",:edit,id: @blog.to_param
  end

  describe "#create_true" do
    @blog = Factory.build(:blogc)
    @req = "post"
    @action = :create
    @params = {blog: @blog.attributes}
    @expects = "redirect"
    @objs = nil
    @result = "true"
    @template = nil
    @rto_path = nil
 
    include_context "Do_Reqest",@req,@action,@params,@expects,@objs,@result,@template,@rto_path
  end

  describe "#create_false" do
    @req = "post"
    @action = :create
    @params = {:blog => nil}
    @expects = "render"
    @objs = nil
    @result = "false"
    @template = "blogs/new"
    @rto_path = nil

    include_context "Do_Reqest",@req,@action,@params,@expects,@objs,@result,@template,@rto_path
  end

  describe "#update_true" do
    @blog = Factory.build(:blogc)
    @req = "put"
    @action = :update
    @params = {id: @blog.to_param, blog: @blog.attributes}
    @expects = "redirect"
    @objs = nil
    @result = "true"
    @template = nil
    @rto_path = nil
 
    include_context "Do_Reqest",@req,@action,@params,@expects,@objs,@result,@template,@rto_path
  end

  describe "#update_false" do
    @blog = Factory.build(:blogc)
    @req = "put"
    @action = :update
    @params = {id: @blog.to_param, blog: {id: nil ,title: nil}}
    @expects = "render"
    @objs = nil
    @result = "false"
    @template = "blogs/edit"
    @rto_path = nil

    include_context "Do_Reqest",@req,@action,@params,@expects,@objs,@result,@template,@rto_path
  end

  describe "#destroy_true" do
    @blog = Factory.build(:blogc)
    @req = "delete"
    @action = :destroy
    @params = {id: @blog.to_param}
    @expects = "redirect"
    @objs = nil
    @result = "true"
    @template = nil
    @rto_path = "blogs_path"

    include_context "Do_Reqest",@req,@action,@params,@expects,@objs,@result,@template,@rto_path
  end


end


BlogsControllerのクリエイトとアップデートアクションです

 # POST /blogs
  # POST /blogs.json


  def create
    @blog = Blog.create(current_user,params[:blog])
    @result = @blog.save

    respond_to do |format|
      if @result
        format.html { redirect_to @blog, notice: 'Blog was successfully updated' }
        format.json { render json: @blog, status: :created, location: @blog }
      else
        format.html { render action: "new" }
        format.json { render json: @blog.errors, status: :unprocessable_entity }
      end
    end
  end

  # PUT /blogs/1
  # PUT /blogs/1.json
  def update
    @blog = Blog.find(params[:id])
    @result = @blog.update_attributes(params[:blog])

    respond_to do |format|
      if @result
        format.html { redirect_to @blog, notice: 'Blog was successfully updated.' }
        format.json { head :ok }
      else
        format.html { render action: "edit" }
        format.json { render json: @blog.errors, status: :unprocessable_entity }
      end
    end

0 件のコメント:

コメントを投稿