我在轨道上的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吗?我想现在用户已登录