Rails测试在过滤器之前设置了实例变量的控制器方法



好的,所以我的主要问题是我已经在我们的项目中实现了Mailboxer来处理消息传递,我正在尝试为它编写测试。然而,我一次又一次地磕磕碰碰。我尝试了几种不同的存根/mock,但没有取得任何进展。

我们有一个conversations_controller.rb,它依赖于before_filters来设置执行每个操作所需的所有实例变量。然后在控制器操作中,直接引用实例变量来执行任何类型的操作或返回特定数据。

下面是我们的索引操作的一个示例,它返回在before_filter中指定的"框"中的所有对话,该框也是在另一个before_filter:中指定的邮箱

class ConversationsController < ::ApplicationController
    before_filter :get_user_mailbox, only: [:index, :new_message, :show_message, :mark_as_read, :mark_as_unread, :create_message, :reply_message, :update, :destroy_message, :untrash]
    before_filter :get_box
    def index
      if @box.eql? "inbox"
        @conversations = @mailbox.inbox
      elsif @box.eql? "sentbox"
        @conversations = @mailbox.sentbox
      else
        @conversations = @mailbox.trash
      end
    end

过滤器之前:

private
def get_user_mailbox
    @user = User.where(:user_name => user.user_name.downcase).where(:email => user.email.downcase).first_or_create
    @mailbox = @user.mailbox if @user
end
def get_box
    if params[:box].blank? or !["inbox","sentbox","trash"].include?params[:box]
      params[:box] = 'inbox'
    end
    @box = params[:box]
end

所以我想我有两个问题。首先,如何让我的测试生成索引操作所需的正确数据@mailbox、@user和@box。接下来,我如何将fake参数设置为不同的"inbox/sentbox/trash"。我尝试过controller.index({box:"inbox"}),但总是收到"0的错误参数1"的邮件。

我尝试过各种不同的方法,但总是零:类错误,这意味着我的实例变量肯定没有正确设置。

describe "GET 'index' returns correct mailbox box" do
  before :each do
    @user = User.where(:user_name => 'test').where(:email => 'test@test.com').first_or_create
    @mailbox = @user.mailbox
  end
  it "#index returns inbox when box = 'inbox'" do
    mock_model User
    User.stub_chain(:where, :where).and_return(@user)
    controller.index.should == @mailbox.inbox
  end
end

过滤器和回调很难测试和调试。尽可能避开它们。

在这种情况下,我认为你的before_filter是不必要的,因此没有必要测试它。对于这些方法来说,更好的家是模型。

查看我的重新获取:

class User < ActiveRecord::Base
  delegate :inbox, :sentbox, :trash, to: :mailbox
end
class ConversationsController < ::ApplicationController
  def index
    @conversations = current_user.send get_box
  end
  private
  def get_box
    # your code
  end
end

仅此而已。应该足够了。

然后你可以定期测试。

首先,阅读rails测试的官方文档:其中解释了使用数据进行测试并将参数传递给控制器。

要为您的测试生成数据,您可以:

  1. 使用rails fixture或使用工厂女孩之类的东西,用一些邮箱和用户填充测试数据库

  2. 使用mock对象伪造数据。我个人使用摩卡宝石,但还有其他

我倾向于两者结合使用,尽可能喜欢mock对象,当mock需要太多代码时,我会回到工厂女孩。

相关内容

  • 没有找到相关文章

最新更新