Ruby on rails Rspec阻止调用方法

Ruby on rails Rspec阻止调用方法,ruby-on-rails,ruby,rspec,mocking,stub,Ruby On Rails,Ruby,Rspec,Mocking,Stub,我正在测试用于创建新订单的控制器方法(类似于电子商务的应用程序)。如果用户在系统中,则应将其重定向到新用户会话路径,否则重定向到新订单路径。就这么简单 这是我的orders\u controller.rb def new if !User.where(phone: params[:phone]).blank? && !user_signed_in? redirect_to new_user_session_path()

我正在测试用于创建新订单的控制器方法(类似于电子商务的应用程序)。如果用户在系统中,则应将其重定向到
新用户会话路径
,否则重定向到
新订单路径
。就这么简单

这是我的
orders\u controller.rb

def new
        if !User.where(phone: params[:phone]).blank? && !user_signed_in?

            redirect_to new_user_session_path()
            flash[:info] = "Already present"
        else
            @order = Order.new
            @menu = Menu.find(params[:menu_id])
            @menu_price = @menu.calculate_price(@menu, params)
        end
    end
在我的应用程序中,我需要调用calculate_price方法,因为它计算给定参数的总价格。但是在我的测试中,我只想确保重定向是正确的

现在我得到了如下错误(它们来源于Menu.rb文件,因为调用了calculate_price):

这是我的规范文件:

require 'rails_helper'


describe Front::OrdersController, type: :controller do
    describe '#new' do
        # Set up dummy menu
        let (:menu) { Menu.create() }

        it "redirects user to sign up page if user is present in the system" do
            user = User.create(name: "Bob", password: "bobspassword", phone: "+7 (903) 227-8874")

            get :new, params: { phone: user.phone }
            expect(response).to redirect_to(new_user_session_path(phone: user.phone))
        end

        it "redirects user to new order page if user is not present in the system" do
            non_present_phone = "+7 (903) 227-8874"    
            get :new, params: { phone: non_present_phone, menu_id: menu.id}
            expect(response).to redirect_to(new_order_path)
        end

    end
end

当然,我可以提供所有的参数,但是有相当多的参数,而且,我只想测试正确的重定向。据我所知,在这种情况下,当您想要显式测试方法时,mock和sub非常有用。但就我而言,我想——不知怎么的——忽略它们。如何确保这种行为?

因此,您只想测试重定向以及执行calculate_price方法时发生的错误。你为什么不干脆用那种方法呢?您的等级库文件可能如下所示:

require 'rails_helper'


describe Front::OrdersController, type: :controller do
    describe '#new' do
        # Set up dummy menu
        let (:menu) { Menu.create() }

        # Check this out
        before do
          allow_any_instance_of(Menu).to receive(:calculate_price)
          # or if you need certain value
          allow_any_instance_of(Menu).to receive(:calculate_price).and_return(your_value)
        end

        it "redirects user to sign up page if user is present in the system" do
            user = User.create(name: "Bob", password: "bobspassword", phone: "+7 (903) 227-8874")

            get :new, params: { phone: user.phone }
            expect(response).to redirect_to(new_user_session_path(phone: user.phone))
        end

        it "redirects user to new order page if user is not present in the system" do
            non_present_phone = "+7 (903) 227-8874"    
            get :new, params: { phone: non_present_phone, menu_id: menu.id}
            expect(response).to redirect_to(new_order_path)
        end

    end
end

谢谢我尝试了一些不同的语法,例如
菜单。任何实例。存根(:date)。和返回(“”
),但是你的语法很有魅力!对于伟大的正义来说,允许任何实例都不是最好的解决方案。这只是轻量级的选择。要使内容更优雅,请创建
菜单
实例,使用其ID作为
参数['Menu\u ID']
(您已经有了它)发出请求。然后存根
calculate\u price
方法调用的不是
菜单的任何实例,而是您的
菜单的实例。这可能会给你带来更多的麻烦,但无论如何,这将是一个更好的选择。
require 'rails_helper'


describe Front::OrdersController, type: :controller do
    describe '#new' do
        # Set up dummy menu
        let (:menu) { Menu.create() }

        # Check this out
        before do
          allow_any_instance_of(Menu).to receive(:calculate_price)
          # or if you need certain value
          allow_any_instance_of(Menu).to receive(:calculate_price).and_return(your_value)
        end

        it "redirects user to sign up page if user is present in the system" do
            user = User.create(name: "Bob", password: "bobspassword", phone: "+7 (903) 227-8874")

            get :new, params: { phone: user.phone }
            expect(response).to redirect_to(new_user_session_path(phone: user.phone))
        end

        it "redirects user to new order page if user is not present in the system" do
            non_present_phone = "+7 (903) 227-8874"    
            get :new, params: { phone: non_present_phone, menu_id: menu.id}
            expect(response).to redirect_to(new_order_path)
        end

    end
end