0
0

More than 3 years have passed since last update.

Railsチュートリアル 第13章 ユーザーのマイクロポスト - 【発展】ユーザー情報のパーシャルとマイクロポスト投稿フォームを、テスト駆動開発で実装する

Last updated at Posted at 2020-01-03

内容

Railsチュートリアル第13章の本文中において、テストが書かれることなしに実装されていた以下2つの要素を、テスト駆動で実装してみようというものです。

  • ユーザー情報のパーシャル
  • マイクロポスト投稿フォーム

Railsチュートリアル本文においては、「マイクロポスト作成フォームのあるホーム画面のモックアップ」として、図 13.10が挙げられています。

ユーザー情報のパーシャルの実装

ユーザー情報のパーシャルに含まれているべき要素に対するテスト

Railsチュートリアル本文によれば、サイドバーで表示されるべきユーザー情報のパーシャルには、以下の要素が含まれている必要があります。

  • gravatar_forクラスを持つimg要素
  • ユーザー名を内容とするh1要素
  • マイクロポスト数を含むspan要素

テストを追加するのはtest/integration/microposts_interface_test.rbです。追加するテストの内容は以下となります。

test/integration/microposts_interface_test.rb
  require 'test_helper'

  class MicropostsInterfaceTest < ActionDispatch::IntegrationTest
    def setup
      @user = users(:rhakurei)
    end

    test "micropost interface" do
      log_in_as(@user)
      get root_path
+     assert_select 'img.gravatar'
+     assert_select 'h1', @user.name
+     assert_select 'span', /#{@user.microposts.count}/
      assert_select 'div.pagination'
      ...略
    end
  end

「指定の文字列が含まれる指定の要素が存在するか」というテスト

例えば「@user.microposts.count変数の内容が記述されているspan要素が存在するか」というテストであれば、以下のように記載します。

assert_select 'span', /#{@user.microposts.count}/

正規表現オブジェクトを意味する//で、変数の内容を展開する#{}を囲っているのがポイントですね。

サイドバーで表示されるべきユーザー情報のパーシャルに対しての、現時点のテスト結果

現時点でのtest/integration/microposts_interface_test.rbに対するテストの結果は、以下のようになります。

# rails test test/integration/microposts_interface_test.rb
Running via Spring preloader in process 120
Started with run options --seed 17602

 FAIL["test_micropost_interface", MicropostsInterfaceTest, 3.629997299999559]
 test_micropost_interface#MicropostsInterfaceTest (3.63s)
        Expected at least 1 element matching "h1", found 0..
        Expected 0 to be >= 1.
        test/integration/microposts_interface_test.rb:12:in `block in <class:MicropostsInterfaceTest>'

  1/1: [===================================] 100% Time: 00:00:03, Time: 00:00:03

Finished in 3.63972s
1 tests, 2 assertions, 1 failures, 0 errors, 0 skips

h1要素が見当たらない」というメッセージを出してテストが失敗しています。

サイドバーで表示するユーザー情報のパーシャルを実装する

まず、サイドバーで表示するユーザー情報のパーシャルの実体を実装していきます。ファイル名はapp/views/shared/_user_info.html.erbとします。

app/views/shared/_user_info.html.erb
<%= link_to gravatar_for(current_user, size: 50), current_user %>
<h1><%= current_user %></h1>
<span><%= link_to "view my profile", current_user %><span>
<span><%= pluralize(current_user.microposts.count, "micropost") %></span>

続いて、Homeページのビューでも当該パーシャルを使用するようにします。変更するファイルはapp/views/static_pages/home.html.erbですね。

app/views/static_pages/home.html.erb
  <% provide(:title, "Home") %>
  <% if logged_in? %>
    <div class="row">
      <aside class="col-md-4">
-       <%#TODO: ユーザー情報表示部の実装 %>
+       <section class="user_info">
+         <%= render 'shared/user_info' %>
+       </section>
        <section class="micropost_form">
          <%= render 'shared/micropost_form' %>
        </section>
      </aside>
      <div class="col-md-8">
        <h3>Micropost Feed</h3>
        <%= render 'shared/feed' %>
      </div>
    </div>
  <% else %>
    ...略
  <% end %>

サイドバーで表示するユーザー情報のパーシャルを実装した時点でのテストの結果

ここまでの実装が完了した時点で、test/integration/microposts_interface_test.rbを対象としてテストを実行すると、結果は以下のようになります。

# rails test test/integration/microposts_interface_test.rb
Running via Spring preloader in process 224
Started with run options --seed 14923

  1/1: [===================================] 100% Time: 00:00:03, Time: 00:00:03

Finished in 3.96801s
1 tests, 13 assertions, 0 failures, 0 errors, 0 skips

テストが成功していますね。ひとまず、サイドバーで表示するユーザー情報のパーシャルは正しく追加できたようです。

マイクロポスト投稿フォームの完全な実装

完全なマイクロポストの投稿フォームに含まれているべき要素に対するテスト

Railsチュートリアル本文によれば、サイドバーで表示されるべきマイクロポスト投稿フォームのパーシャルには、以下の要素が含まれている必要があります。

  • /microposts に対してPOSTアクションを行うフォーム
  • マイクロポスト本文を入力するためのテキストフィールド
test/integration/microposts_interface_test.rb
  require 'test_helper'

  class MicropostsInterfaceTest < ActionDispatch::IntegrationTest
    def setup
      @user = users(:rhakurei)
    end

    test "micropost interface" do
      log_in_as(@user)
      get root_path
      assert_select 'img.gravatar'
      assert_select 'h1', @user.name
      assert_select 'span', /#{@user.microposts.count}/
+     assert_select 'form[action="/microposts"]'
+     assert_select 'textarea'
      assert_select 'div.pagination'
      ...略
    end
  end

マイクロポスト投稿フォームに対するテストを実装した時点でのテストの結果

上記マイクロポスト投稿フォームに対するテストを実装した時点で、microposts_interface_test.rbに対してテストを実行してみましょう。

# rails test test/integration/microposts_interface_test.rb
Running via Spring preloader in process 276
Started with run options --seed 9808

 FAIL["test_micropost_interface", MicropostsInterfaceTest, 3.1817765000014333]
 test_micropost_interface#MicropostsInterfaceTest (3.18s)
        Expected at least 1 element matching "textarea", found 0..
        Expected 0 to be >= 1.
        test/integration/microposts_interface_test.rb:15:in `block in <class:MicropostsInterfaceTest>'

  1/1: [===================================] 100% Time: 00:00:03, Time: 00:00:03

Finished in 3.19284s
1 tests, 5 assertions, 1 failures, 0 errors, 0 skips

textarea要素が存在しない」というメッセージを出力してテストが失敗しています。

マイクロポスト投稿フォームの完全な実装

Railsチュートリアル本文によれば、マイクロポスト投稿フォームの完全な実装は以下の通りになります。

<%= form_for(@micropost) do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
  <div class="field">
    <%= f.text_area :content, placeholder: "Compose new micropost..." %>
  </div>
  <%= f.submit "Post", class: "btn btn-primary" %>
<% end %>

対応するソースファイルはtest/integration/microposts_interface_test.rbです。

ここまでの実装で、エラーメッセージのパーシャルが出力できるようにするための実装は完了しています。新たに追加する必要があるのは以下の2つですね。

  • マイクロポスト本文を入力するためのテキストフィールド
  • 送信ボタン

早速実装を追加していきましょう。

app/views/shared/_micropost_form.html.erb
  <%= form_for(@micropost) do |f| %>
    <%= render 'shared/error_messages', object: f.object %>
+   <div class="field">
+     <%= f.text_area :content, placeholder: "Compose new micropost..." %>
+   </div>
+   <%= f.submit "Post", class: "btn btn-primary" %>
  <% end %>

マイクロポスト投稿フォームの完全な実装を終えた時点でのテストの結果

test/integration/microposts_interface_test.rbに対し、改めてテストを実行してみましょう。

# rails test test/integration/microposts_interface_test.rb
Running via Spring preloader in process 341
Started with run options --seed 28502

  1/1: [===================================] 100% Time: 00:00:04, Time: 00:00:04

Finished in 4.07368s
1 tests, 15 assertions, 0 failures, 0 errors, 0 skips

今度こそテストが成功しました。

テストスイート全体に対するテストの結果はどうでしょうか。

# rails test
Running via Spring preloader in process 354
Started with run options --seed 14679

  59/59: [=================================] 100% Time: 00:00:11, Time: 00:00:11

Finished in 11.81368s
59 tests, 321 assertions, 0 failures, 0 errors, 0 skips

テストスイート全体に対しても、無事テストが成功しましたね。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0