Ruby / Rails

AjaxをSystem specでテストする書き方

2019年10月11日

こんにちは、Nanayakuです。

自分は「Ajaxを用いた動的なコメント投稿・削除機能の実装で学ぶRuby on Rails - 銀行員からのRailsエンジニア」を参考にAjaxを実装しました。

その時、RSpecのSystem specでエラーが発生したので、その対策を紹介します。

テスト内容

自分は、下記のようなコメントをして、そのコメントが表示されているかのテストを作成しました。

require 'rails_helper'
require 'spec_helper'

RSpec.feature 'Comments', type: :system do
  before do
    @user = User.create(
      name: 'TEST_USER',
      email: 'test@example.com',
      password: 'password1234'
    )
    visit root_path
    visit login_path
    fill_in 'sesstion_email', with: 'test@example.com'
    fill_in 'sesstion_password', with: 'password1234'
    click_on 'ログインする'
    @micropost = Micropost.create(
      content: 'test',
      user_id: @user.id
    )
  end

#コメントのテスト
  it 'コメントする', js: true do
    visit microposts_path
    click_on 'test'
    fill_in 'user_new_comment', with: 'test_comment'
    click_button 'コメントをする'
    expect(page).to have_content 'test_comment'
  end
end

 

エラーの原因

Ajaxの仕組みについては、「Ajaxを用いた動的なコメント投稿・削除機能の実装で学ぶRuby on Rails - 銀行員からのRailsエンジニア」で分かりやすく説明しているので、こちらを読んでください。

今回発生したエラーは、コメントを保存した後、レンダリングするファイルがないと言うエラーでした。

どう言うことかと言うと、「render :index」は、views/commentsディレクトリ内にあるindex.erbファイルを返します。

しかし、views/commentsディレクトリ内には、「_form.html.erb」「_index.html.erb」「index.js.erb」の3つしかないため、index.erbファイルを作るかどうにかしろと言うエラーが発生します。

このエラーを解決するには、ファイル名で指定する書き方をすればOKです。

【Rails】部分テンプレートの使い方を徹底解説! | ピカわか! - ピカ1わかりやすいプログラミング用語サイトにあるように、「render」はアクション名とファイル名を指定できます。

下記のように、「index.js.erb」を指定すればエラーは発生しません。

class CommentsController < ApplicationController
  before_action :login_check
  def create
    @micropost = Micropost.find(params[:micropost_id])
    @comment = @micropost.comments.build(comment_params)
    @comment.user_id = current_user.id
    if @comment.save
      render 'index.js.erb'# <=ここ
    else
      redirect_to micropost_path(@comment.micropost), danger: 'コメントに失敗しました'
    end
  end

  def destroy
    @micropost = Micropost.find(params[:micropost_id])
    @comment = @micropost.comments.find(params[:comment_id])
    if @comment.destroy
      render 'index.js.erb'
    else
      redirect_to micropost_path(@comment.micropost.id), danger: 'コメントの削除に失敗しました'
    end
  end

  private

  def comment_params
    params.require(:comment).permit(:comment, :micropost_id, :user_id)
  end
end

 

参考サイト

レイアウトとレンダリング | Rails ガイド

【Rails】部分テンプレートの使い方を徹底解説! | ピカわか! - ピカ1わかりやすいプログラミング用語サイト

 

最後に

今回のエラーは、「render」の仕様についてちゃんと理解していなかった事が、1番の原因でした。

使っているメソッドについて、しっかり理解しておく事が大事です。

-Ruby / Rails
-

© 2021 Nanayaku blog Powered by AFFINGER5