0
0

More than 3 years have passed since last update.

Railsチュートリアル 第13章 ユーザーのマイクロポスト - Micropostモデルに、テスト駆動で新たな機能を追加していく

Posted at

空文字列での投稿は受け付けない

「空文字列で投稿した場合、Micropostオブジェクトは有効ではない」というテストを追加する

「空文字列で投稿した場合、Micropostオブジェクトは有効ではない」とすれば、上述の機能は実現されます。対応するテストは、以下のようになります。名前は「content should be present」とします。

test "content should be present" do
  @micropost.content = "  "
  assert_not @micropost.valid?
end

上記テストをtest/models/micropost_test.rbに追加します。

test/models/micropost_test.rb
  require 'test_helper'

  class MicropostTest < ActiveSupport::TestCase
    def setup
      @user = users(:rhakurei)
      #HACK: このコードは慣習的に正しくないため、要修正
      @micropost = Micropost.new(content: "Lorem ipsum", user_id: @user.id)
    end

    test "should be valid" do
      assert @micropost.valid?
    end

    test "user id should be present" do
      @micropost.user_id = nil
      assert_not @micropost.valid?
    end
+
+   test "content should be present" do
+     @micropost.content = "  "
+     assert_not @micropost.valid?
+   end
  end

「空文字列で投稿した場合、Micropostオブジェクトは有効ではない」テストを追加した時点でのテストの結果

# rails test test/models/micropost_test.rb
Running via Spring preloader in process 1355
Started with run options --seed 47132

 FAIL["test_content_should_be_present", MicropostTest, 0.2884534999902826]
 test_content_should_be_present#MicropostTest (0.29s)
        Expected true to be nil or false
        test/models/micropost_test.rb:21:in `block in <class:MicropostTest>'

  3/3: [===================================] 100% Time: 00:00:00, Time: 00:00:00

Finished in 0.79459s
3 tests, 3 assertions, 1 failures, 0 errors, 0 skips

test/models/micropost_test.rbに対するテストは、上記のような結果を返して失敗します。

私の環境では、test/models/micropost_test.rbの20行目から21行目は以下のようになっています。

test/models/micropost_test.rb(20〜21行目)
@micropost.content = "  "
assert_not @micropost.valid?

「空のマイクロポストを受け付けてしまっている」という失敗ですね。想定通りのテストが実装できているといえます。

「空文字列での投稿は受け付けない」という機能の追加

Micropostモデルに、以下のようなバリデーションを追加すればOKです。「マイクロポストには内容が存在している必要がある」というバリデーションですね。

validates :content, presence: true
app/models/micropost.rb
  class Micropost < ApplicationRecord
    belongs_to :user
+   validates :content, presence: true
  end

「空文字列で投稿した場合、Micropostオブジェクトは有効ではない」テストが成功することを確認する

上記実装を追加した時点で、改めてtest/models/micropost_test.rbに対するテストを実行してみます。

# rails test test/models/micropost_test.rb
Running via Spring preloader in process 1368
Started with run options --seed 43879

  3/3: [===================================] 100% Time: 00:00:00, Time: 00:00:00

Finished in 0.79976s
3 tests, 3 assertions, 0 failures, 0 errors, 0 skips

今度は成功しました。「空文字列での投稿は受け付けない」という機能を正しく追加できたといえますね。

マイクロポストの長さを140文字以内に制限する

「マイクロポストの文字数が141文字以上の場合、Micropostオブジェクトは有効ではない」とすれば、上述の機能は実現されます。対応するテストは、以下のようになります。名前は「content should be at most 140 characters」とします。

test "content should be at most 140 characters" do
  @micropost.content = "a" * 141
  assert_not @micropost.valid?
end

上記テストをtest/models/micropost_test.rbに追加します。

test/models/micropost_test.rb
  require 'test_helper'

  class MicropostTest < ActiveSupport::TestCase
    def setup
      @user = users(:rhakurei)
      #HACK: このコードは慣習的に正しくないため、要修正
      @micropost = Micropost.new(content: "Lorem ipsum", user_id: @user.id)
    end

    test "should be valid" do
      assert @micropost.valid?
    end

    test "user id should be present" do
      @micropost.user_id = nil
      assert_not @micropost.valid?
    end

    test "content should be present" do
      @micropost.content = "  "
      assert_not @micropost.valid?
    end
+
+   test "content should be at most 140 characters" do
+     @micropost.content = "a" * 141
+     assert_not @micropost.valid?
+   end
  end

141文字の文字列を手っ取り早く生成する方法

(復習)Rubyにおいて141文字の文字列を生成するためには、文字列の乗算を使う方法が手っ取り早いです。

# rails console
>> "a" * 141
=> "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

「マイクロポストの文字数が141文字以上の場合、Micropostオブジェクトは有効ではない」テストを追加した時点でのテストの結果

# rails test test/models/micropost_test.rb
Running via Spring preloader in process 1381
Started with run options --seed 7585

 FAIL["test_content_should_be_at_most_140_characters", MicropostTest, 0.22907639999175444]
 test_content_should_be_at_most_140_characters#MicropostTest (0.23s)
        Expected true to be nil or false
        test/models/micropost_test.rb:26:in `block in <class:MicropostTest>'

  4/4: [===================================] 100% Time: 00:00:00, Time: 00:00:00

Finished in 0.72279s
4 tests, 4 assertions, 1 failures, 0 errors, 0 skips

test/models/micropost_test.rbに対するテストは、上記のような結果を返して失敗します。

私の環境では、test/models/micropost_test.rbの25行目から26行目は以下のようになっています。

test/models/micropost_test.rb(25〜26行目)
@micropost.content = "a" * 141
assert_not @micropost.valid?

「141文字のマイクロポストを受け付けてしまっている」という失敗ですね。想定通りのテストが実装できているといえます。

「マイクロポストで受け付ける文字数は140文字まで」という機能の追加

Micropostモデルのバリデーションを、以下のように変更すればOKです。「マイクロポストには内容が存在しており、かつ文字数は140以下である必要がある」というバリデーションですね。

app/models/micropost.rb
  class Micropost < ApplicationRecord
    belongs_to :user
-   validates :content, presence: true
+   validates :content, presence: true, length: { maximum: 140 }
  end

「マイクロポストの文字数が141文字以上の場合、Micropostオブジェクトは有効ではない」テストが成功することを確認する

上記実装を追加した時点で、改めてtest/models/micropost_test.rbに対するテストを実行してみます。

# rails test test/models/micropost_test.rb
Running via Spring preloader in process 1402
Started with run options --seed 39026

  4/4: [===================================] 100% Time: 00:00:00, Time: 00:00:00

Finished in 0.77221s
4 tests, 4 assertions, 0 failures, 0 errors, 0 skips

今度は成功しました。「マイクロポストで受け付ける文字数は140文字まで」という機能を正しく追加できたといえますね。

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