Rails - assert_redirect_to,带有未知参数

时间:2016-11-26 21:28:54

标签: ruby-on-rails ruby unit-testing

我构建了一个Rails应用程序,其中包含可以提供随机配方的功能:

class RecipesController < ApplicationController

    # GET /recipes/shuffle
    # get a random recipe and redirect user on this
    def shuffle
        offset = rand Recipe.count
        random  = Recipe.offset(offset).first
        redirect_to recipe_path random
    end

end

它工作得很好,但我想在这条路线上建立一个测试

require 'test_helper'

class RecipesControllerTest < ActionController::TestCase

  test "should be redirect to a random recipe path" do
    get :shuffle
    assert_redirected_to(  controller: "recipes", action: "show"  ) 
  end

end

但实际上它不起作用,因为我收到此错误消息:

  

ActionController :: UrlGenerationError:没有路由匹配{:action =&gt;“show”,:controller =&gt;“recipes”}

这是我的 route.rb

RaspberryCook::Application.routes.draw do

  resources :recipes, :only => [:index, :new , :create , :destroy , :edit]
  get     'recipes/:id' ,         to: 'recipes#show', id: /[0-9]+/
  patch  'recipes/:id' ,         to: 'recipes#update', id: /[0-9]+/
  get    'recipes/shuffle' ,      to: 'recipes#shuffle'
  post    'recipes/import' ,      to: 'recipes#import'

end

那么如何构建我的测试,例如“应该获得一个带有未知ID的随机食谱”?

2 个答案:

答案 0 :(得分:1)

在这种情况下,您在控制器方法中生成了一个无法通过测试访问的变量。

引用被测试方法的内部变量是一个常见的要求,“模拟”或“存根”的注释是有帮助的。

在这里,您可以存根rand调用的结果以返回预定数字。这一切都可以在测试用例中完成:

id = 1
expect(Kernel).to receive(:rand).with(Recipe.count).and_return(id)
get :shuffle
assert_redirected_to(controller: "recipes", action: "show", id: id) 

答案 1 :(得分:0)

我自己找到了一个解决方案,我使用了一个简单的正则表达式匹配器:

require 'test_helper'

class RecipesControllerTest < ActionController::TestCase

  test "should be redirect to a random recipe path" do
    get :shuffle
    assert_redirected_to %r(/recipes/[0-9]+)
  end

end

很容易,但它可以完成任务!