空文字列での投稿は受け付けない
「空文字列で投稿した場合、Micropostオブジェクトは有効ではない」というテストを追加する
「空文字列で投稿した場合、Micropostオブジェクトは有効ではない」とすれば、上述の機能は実現されます。対応するテストは、以下のようになります。名前は「content should be present」とします。
test "content should be present" do
@micropost.content = " "
assert_not @micropost.valid?
end
上記テストを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行目は以下のようになっています。
@micropost.content = " "
assert_not @micropost.valid?
「空のマイクロポストを受け付けてしまっている」という失敗ですね。想定通りのテストが実装できているといえます。
「空文字列での投稿は受け付けない」という機能の追加
Micropostモデルに、以下のようなバリデーションを追加すればOKです。「マイクロポストには内容が存在している必要がある」というバリデーションですね。
validates :content, presence: true
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
に追加します。
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行目は以下のようになっています。
@micropost.content = "a" * 141
assert_not @micropost.valid?
「141文字のマイクロポストを受け付けてしまっている」という失敗ですね。想定通りのテストが実装できているといえます。
「マイクロポストで受け付ける文字数は140文字まで」という機能の追加
Micropostモデルのバリデーションを、以下のように変更すればOKです。「マイクロポストには内容が存在しており、かつ文字数は140以下である必要がある」というバリデーションですね。
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文字まで」という機能を正しく追加できたといえますね。