测试控制器失败:NoMethodError:nil的未定义方法`env':NilClass

时间:2016-12-05 11:24:12

标签: ruby-on-rails unit-testing

我在轨道上的ruby中进行单元测试时遇到问题(rails v.5.001)。用户需要登录测试单元,但我该如何实现呢?这是代码:

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。现在我的appointmentments_controller_test.rb看起来像这样:

 require 'test_helper'

class AppointmentsControllerTest < ActionDispatch::IntegrationTest

 include Devise::Test::IntegrationHelpers

  def sign_in(user)
    post user_session_path \
      "heiko@me.com"    => 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 个答案:

没有答案