2016-12-05 64 views
0

我在rails上的ruby單元測試有問題(rails v。5.001)。用戶需要在測試單元中登錄,但我該如何實現?下面是代碼:測試控制器失敗:NoMethodError:未定義的方法`env'爲零:NilClass

appointments_controller_test.rb

require 'test_helper' 

class AppointmentsControllerTest < ActionDispatch::IntegrationTest 
    include Devise::TestHelpers 
    setup do 
    @heikoAppointment = appointments(:appointment_heiko) 
    @heiko = users(:heiko) 
    heiko = users(:heiko) 

    end 

    test "should get index" do 
    get appointments_url 
    assert_response :success 
    end 

    test "should get new" do 
    sign_in @heiko 
    get new_appointment_url 
    assert_response :success 
    end 

......

appointments_controller.rb

class AppointmentsController < ApplicationController 
    load_and_authorize_resource 
    layout 'appointment', only: [:shopper_show, :senior_show] 

    def index 
    @shopping_lists = ShoppingList.where(user_id: current_user.id) 
    @users = User.senior.where.not(id: current_user.id).order(:firstname) 

    #@appointments = Appointment.where(user_id: current_user.id) 
    #@invitations = Invitation.where(user_id: current_user.id) 
    #todo: merge @invitations.appointmen into @appointments 
    end 

    # GET /shopping_processes/1 
    # GET /shopping_processes/1.json 
    def show 
    @appointment = Appointment.find(params[:id]) 
    @shopping_lists = get_both_lists 
    @users = get_both_users 
    end 

    # POST /shopping_processes 
    # POST /shopping_processes.json 
    def create 
    @appointment.status = nil 
    @appointment.processed = nil 
    @appointment.user_id = current_user.id 

    sl_created = create_shopping_list? 

    respond_to do |format| 
     if @appointment.save 
     format.html { redirect_to @appointment, notice: t(:appointment_created) } 
     format.json { render :show, status: :created, location: @appointment } 
     else 
     if sl_created 
      ShoppingList.find(@appointment.shopping_list_id).destroy 
     end 
     format.html { render :new } 
     format.json { render json: @appointment.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    # PATCH/PUT /shopping_processes/1 
    # PATCH/PUT /shopping_processes/1.json 
    def update 
    respond_to do |format| 
     if @appointment.update(appointment_params) 
     format.html { redirect_to @appointment, notice: t(:appointment_updated) } 
     format.json { render :show, status: :ok, location: @appointment } 
     else 
     format.html { render :edit } 
     format.json { render json: @appointment.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    # DELETE /shopping_processes/1 
    # DELETE /shopping_processes/1.json 
    def destroy 
    @appointment.destroy 
    respond_to do |format| 
     format.html { redirect_to appointments_url, notice: t(:appointment_deleted) } 
     format.json { head :no_content } 
    end 
    end 

    def shopper_index 
    end 

    def ready_index 
    appointments_hash = {} 

    customers = User.where.not(current_appointment: nil).where(role: :senior) 
    customers.each {|user| appointments_hash[user.current_appointment.id] = user.current_appointment} 

    shoppers = User.where.not(current_appointment: nil).where(role: :shopper) 
    shoppers.each {|user| appointments_hash.delete(user.current_appointment.id)} 

    @appointments = [] 
    appointments_hash.each { |appointment_id, appointment| @appointments.push(appointment)} 
    end 

    def shopper_show 
    @appointment = Appointment.find(params[:id]) 
    @shopping_lists = get_both_lists 

    both_users = get_both_users 
    @users = {} 
    first = true 
    both_users.each do |user| 
     @users[user.id] = {color: (first ? 'blue' : 'yellow'), name: user.firstname + ' ' + user.lastname} 
     first = false 
    end 
    end 

    def senior_show 
    @appointment = Appointment.find(params[:id]) 

     if @appointment.user == current_user 
     @shopping_list = @appointment.shopping_list 
     else 
     @shopping_list = @appointment.invitation.shopping_list 
     end 

    #D.S.:Diese zuweisung funktioniert nicht richtig. Sie wurde vor den DB änderung erstellt und muss angepasst werden 
    #D.S.:ShoppingItem.joins(:list_item) und ListItem.where(shopping_list_id: @shopping_list.id]) ergeben ein korrektes Resultat 
    #D.S.:Aber zusammengenommen ist die query leer 
    #@shopping_items = ShoppingItem.joins(:list_item).where(list_item: [shopping_list_id: @shopping_list.id]) 
    end 

    private def get_both_lists 
    shopping_lists = [ @appointment.shopping_list] 

    if @appointment.invitation && @appointment.invitation.shopping_list 
     shopping_lists << @appointment.invitation.shopping_list 
    end 

    shopping_lists 
    end 

    private def get_both_users 
    users = [ @appointment.user] 

    if @appointment.invitation 
     users.push(@appointment.invitation.user) 
    end 

    users 
    end 

    private 
    # Use callbacks to share common setup or constraints between actions. 
    def set_appointment 
     @appointment = Appointment.find(params[:id]) 
    end 

    # Never trust parameters from the scary internet, only allow the white list through. 
    def appointment_params 
     params.require(:appointment).permit(:shopper_id, :status, :appointed, :processed, :shopping_list_id, invitation_attributes: [:user_id, :message ]) 
    end 

    def create_shopping_list? 
    if @appointment.shopping_list_id.blank? 
     name = "Liste für den " + @appointment.appointed.strftime("%d.%m.%Y").to_s 
     invitee_id = "" + (@appointment.invitation.user_id.to_s) if @appointment.invitation 
     name = name + (" mit " + User.find(invitee_id).firstname) unless invitee_id.blank? 
     sl = current_user.shopping_lists.create(:name => name) 
     @appointment.shopping_list_id = sl.id 
     true 
    else 
     false 
    end 
    end 
end 

,這裏是錯誤,我得到當我運行測試時:

Error: 
AppointmentsControllerTest#test_should_get_new: 
NoMethodError: undefined method `env' for nil:NilClass 

有人知道解決方案嗎?我會非常感謝

更新:包括Devise :: TestHelpers已棄用。現在我使用include Devise :: Test :: IntegrationHelpers。現在我appointments_controller_test.rb看起來是這樣的:

require 'test_helper' 

class AppointmentsControllerTest < ActionDispatch::IntegrationTest 

include Devise::Test::IntegrationHelpers 

    def sign_in(user) 
    post user_session_path \ 
     "[email protected]" => user.email, 
     "hhdk#s0" => user.password 
    end 

    setup do 
    @heikoAppointment = appointments(:appointment_heiko) 
    @heiko = users(:user_heiko) 
    sign_in(@heiko) 
    end 

    test "should get index" do 
    get appointments_url 
    assert_response :success 
    end 

    test "should get new" do 
    sign_in(@heiko) 
    get new_appointment_url 
    assert_response :success 
    end 

但是我得到另一個錯誤:

AppointmentsControllerTest#test_should_get_new [C:/Users/Clemens/meindorfladen/Server/test/controllers/appointments_controller_test.rb:33]: 
Expected response to be a <2XX: success>, but was a <302: Found> redirect to <http://www.example.com/users/sign_in> 

是否有人知道爲什麼會存在這種重定向到http://www.example.com/users/sign_in?我認爲現在用戶已登錄

+0

您是使用Devise還是自己的認證方案? – max

+0

我正在使用devise – Peter

回答

1

根據readme,您應該包括Devise::Test::IntegrationHelpers而不是Devise::TestHelpers

+0

我相信包括'Devise :: TestHelpers'也會折舊,並且應該給出折舊警告。如果您有使用'ActionDispatch :: ControllerTest'的遺留控制器測試,則可以包含'Devise :: Test :: IntegrationHelpers'或'Devise :: Test :: ControllerHelpers'。 – max

+0

我改成包含Devise :: Test :: IntegrationHelpers。現在登錄作品。但是我在should_get_new中得到這個錯誤:期望的響應是<2XX:success>,但是是<302: Found>重定向到 Peter

+0

然後你需要做一些調試以找到了解導致重定向的原因。看看'logs/test.log'會指出你正確的方向。 – max

相關問題