assert_validが欲しい

捨てる予定だったRails2.3プロジェクトをRails5まで上げることになり、 今Rails3でtest-unitとtest-unit-railsを使ってテストを書いています。 そして、test-unitにassert_validが欲しいのです。 内容としては

sub_test_case "#demand_complete" do
  setup do
    @user = User.find_by_id(1)
    login_as @user
  end

  sub_test_case "ご意見ご感想の送信成功" do
    test "ユーザのHOMEにリダイレクト" do
      post "demand_complete", :demand => {:comment => "感想です"}
      assert assigns[:demand].valid?
      assert_redirected_to top_path
    end
  end
end

この、assert assigns[:demand].valid?の部分なのですが、 結果がtrueかfalseしか出てこないので、わざわざerrorsの中身をみる必要がでてくるので テストに手間がかかるのです。こんな感じにしか見えません。 これではなぜvalidじゃないかがわからないのです。

Failure: <false> is not true.
test: ユーザのHOMEにリダイレクト(UsersControllerTest::#demand_complete::ご意見ご感想の送信成功)
test/functional/users_controller_test.rb:339:in `block (3 levels) in <class:UsersControllerTest>'
     336:     sub_test_case "ご意見ご感想の送信成功" do
     337:       test "ユーザのHOMEにリダイレクト" do
     338:         post "demand_complete", :demand => {:comment => ""}
  => 339:         assert assigns[:demand].valid?
     340:         assert_redirected_to top_path
     341:       end
     342:     end

今は知らないけど、昔のrspecには.should be_validとかあるようです。 まあ、rspecはおいといて、assert_validを用意して、validじゃない場合は errorsの中身を表示したい。というわけで、test_helperに定義してみます。 assert_nilあたりを参考にして、errorsの中身を表示するようにしてみます。

def assert_valid(object, message="")
  full_message = build_message(message, <<EOT, object.errors)
<?>
expected to be not valid.
EOT
  assert_block(full_message) { object.valid? }
end

このように定義しておいて、

test "ユーザのHOMEにリダイレクト" do
  post "demand_complete", :demand => {:comment => ""}
  assert_valid assigns[:demand]
  assert_redirected_to top_path
end

結果は

Failure:
  <#<ActiveModel::Errors:0x007fc49cc142c0
   @base=
    #<Demand id: nil, user_id: 1, name: "ラビックス タロウ1", email: "sample+0@example.com", comment: "", deleted_at: nil, created_at: nil, updated_at: nil>,
   @messages={:comment=>["を入力してください"]}>>
  expected to be not valid.
test: ユーザのHOMEにリダイレクト(UsersControllerTest::#demand_complete::ご意見ご感想の送信成功)
test/test_helper.rb:38:in `assert_valid'
test/functional/users_controller_test.rb:339:in `block (3 levels) in <class:UsersControllerTest>'
     336:     sub_test_case "ご意見ご感想の送信成功" do
     337:       test "ユーザのHOMEにリダイレクト" do
     338:         post "demand_complete", :demand => {:comment => ""}
  => 339:         assert_valid assigns[:demand]
     340:         assert_redirected_to top_path
     341:       end
     342:     end

こんな結果になりました。 test_helperの行が出てくるのですが、消し方を調べるのがめんどかったので、 とりあえず放置で。誰か知っていたら教えて下さい。