2016-07-12 115 views
0

之前我问这个问题我想给出一些关于模型的背景。我有一个user_conversation模型(通过表),它接受来自对话和消息模型的属性。下面给出创建操作和操作之前。在rails中测试嵌套属性

before_action :logged_in_user 
before_action :validate_conversation, only: :create 

    def create 
     redirect_to home_path unless current_user 
     @conversation = UserConversation.new conversation_params 
     @conversation.user = current_user 
     @conversation.conversation.messages.first.user = current_user 
     @conversation.save! 
     activate_unread 
     redirect_to user_conversation_path(current_user,@conversation) 
     end 

Private 

def validate_conversation 
     @user = User.find params[:user_id] 
     if params[:user_conversation][:conversation_attributes]["subject"].blank? 
      redirect_to new_user_conversation_path(@user) 
      flash[:danger] = "Subject cannot be blank" 
     else params[:user_conversation][:conversation_attributes][:messages_attributes]["0"]["body"].blank? 
      redirect_to new_user_conversation_path(@user) 
      flash[:danger] = "Message cannot be blank" 
     end 
    end 

def conversation_params 
    params.require(:user_conversation).permit(:recipient_id, conversation_attributes: [:subject, messages_attributes: [:body]]) 
end 

我正在尝试为user_conversation的发布请求编写集成测试。测试如下。

require 'test_helper' 

class ConversationCreateTest < ActionDispatch::IntegrationTest 

    def setup 
    @user = users(:user_a) 
    @conversation = conversations(:convo_one) 
    end 

    test "invalid creation of a user conversation no subject" do 
    log_in_as(@user) 
    get new_user_conversation_path(@user) 
    post user_conversations_path(@user), user_conversation: {:recipient_id => @user.id, :conversation_attributes => {:subject => "this is a subject", 
                   :message_attributes => {"0" => {:body => "sending a message"}}}} 
    end 

当我运行该命令时出现以下错误消息。

1) Error: 
ConversationCreateTest#test_invalid_creation_of_a_user_conversation_no_subject: 
NoMethodError: undefined method `[]' for nil:NilClass 
    app/controllers/user_conversations_controller.rb:63:in `validate_conversation' 
    test/integration/conversation_create_test.rb:13:in `block in <class:ConversationCreateTest>' 

191 runs, 398 assertions, 0 failures, 1 errors, 0 skips 

我一直在试图调试大约2个小时的问题。我检查了测试日志文件,它说内部服务器错误500.我尝试评论某些代码行来缩小问题的范围,但不确定问题是什么。任何帮助,将不胜感激。

+1

如果'params [:user_conversation]'为空,那么当您尝试运行'params [:user_conversation] [:conversation_attributes]'时,代码会爆炸'...您必须测试该行的每个部分......或者更好的是......你不应该在控制器中进行验证 - 这就是模型的用途。 –

+0

@TarynEast,我测试了模型中的验证,他们工作得很好。我只想测试发布请求。我认为这个错误是说其中的一个参数是零。 – kpaul

+0

“只是想测试发布请求”是指你脑袋里的东西,你还没有向我们大声说出:)如果验证在模型中工作,那么你为什么要在控制器中写一个?它实际上不应该在那里......而你的代码失败的最可能的原因是因为'params [:user_conversation]'在某个时候是空白的......你为什么不从你的控制器中完全删除before_action - 然后将该逻辑移入模型中,看看会发生什么。 –

回答

0

在导轨中,使用ActiveModel::Validators进行验证。

所以,你可以简单地验证你的模型是这样的:

用户:

class User 
    has_many :conversations, through: "user_conversations" 
end 

对话:

class Conversation 
    has_many :users, through: "user_conversations" 

    validates_presence_of :subject, :messages 
end 

See more here about validations

所以,如果你再需要验证你的模型你可以拨打电话:

conversation = Conversation.create(subject: nil) 
conversation.errors.full_messages # => ["Subject can't be blank"] 

我认为你需要在你的应用中重写一堆东西,如果你拿了上面的代码,你可以简单地在模型(单元)测试中测试这个东西。

顺便说一下,这不再需要,因为你不想测试rails提供的验证器。你可能只是想测试你自己的验证器。