Rspec 防止方法被调用

moh*_*del 4 ruby rspec ruby-on-rails mocking stub

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

这是我的orders_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
Run Code Online (Sandbox Code Playgroud)

在我的应用程序中,我需要调用calculate_price方法,因为它计算给定参数的总价格。但在我的测试中,我只想确保重定向是正确的。

现在我收到类似的错误(它们源自 Menu.rb 文件,因为调用了calculate_price):

Front::OrdersController#new redirects user to new order page if user is not present in the system
     Failure/Error: menu_price_change = menu_amount.split(",")[1].gsub(" ","").gsub("]",'')

     NoMethodError:
       undefined method `split' for nil:NilClass
Run Code Online (Sandbox Code Playgroud)

这是我的规格文件:

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
Run Code Online (Sandbox Code Playgroud)

当然,我可以提供所有参数,但参数数量相当大,而且我只想测试正确的重定向。据我所知,当您想要显式测试方法时,模拟和子在这种情况下很有用。但就我而言,我想——以某种方式——忽略它们。我怎样才能确保这种行为?

VAD*_*VAD 5

因此,您只想测试重定向,但执行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
Run Code Online (Sandbox Code Playgroud)