好的,所以我的主要问题是我已经在我们的项目中实现了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测试的官方文档:其中解释了使用数据进行测试并将参数传递给控制器。
要为您的测试生成数据,您可以:
-
使用rails fixture或使用工厂女孩之类的东西,用一些邮箱和用户填充测试数据库
-
使用mock对象伪造数据。我个人使用摩卡宝石,但还有其他
我倾向于两者结合使用,尽可能喜欢mock对象,当mock需要太多代码时,我会回到工厂女孩。