質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.59%

エラー文の日本語表記に伴いテストコードも日本語表記に書き換えたがうまくいかない

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,307

score 5

前提・実現したいこと

Ruby on Railsを用いてフリーマーケットアプリを作成しています
商品出品においてフォームを正しく記入しないとエラーが出てリダイレクトしエラー文を発行してくれる仕組みになっていてテストコードまで完成させうまくテストまでできました。
ここからが本題なのですが、
ここでgem 'rails-i18n'を使用し英語表記のエラー文を日本語表記に変更しました
そしてテストコードも同様に日本語表記に直したのですがそこでエラーが出てしまいうまくいきません
これを今回解決したいです

発生している問題・エラーメッセージ

ターミナル使用時のエラー

 1) Item 商品出品 商品出品できない時 itemが空だと出品できない
     Failure/Error: expect(@item.errors.full_messages).to include('商品の名前を入力してください')
       expected ["Item can't be blank"] to include "商品の名前を入力してください"
     # ./spec/models/item_spec.rb:17:in `block (4 levels) in <top (required)>'```  

config/application.rbに 『config.i18n.default_locale = :ja』と言う記述も忘れずに行い

ja:  
activerecord:  
attributes:  
user:  
nickname: ニックネーム  
familyname_kanji: 苗字(漢字)  
firstname_kanji: 名前(漢字)  
familyname_katakana: 苗字(カナ)  
firstname_katakana: 名前(カナ)  
birthday: 生年月日  
item:  
item: 商品の名前  
image: 画像  
text: テキスト  
category_id: カテゴリー  
status_id: 商品の状態  
delivery_burden_id: 配送料の負担  
shipping_origin_id: 発送元の地域  
arrival_day_id: 発送までの日数  
price: 価格  
activemodel:  
attributes:  
purchase_house_add:  
postal_code: 郵便番号  
shipping_origin_id: 都道府県  
city: 市区町村  
address: 番地  
phone: 電話番号  

ja.ymlには上記のように記述しdevise.ja.ymlも忘れず作成しました

item_spec.rb

~省略~  

context '商品出品できない時' do  
it 'itemが空だと出品できない' do  
@item.item = nil  
@item.valid?  
expect(@item.errors.full_messages).to include('商品の名前を入力してください')  
end  

~省略~  


それを踏まえてこのように記述したが先程のターミナルで表示されたエラーが発生してしまいます。

試したこと

自分の記述ミスなども考えエラー文を表示させてからそれをコピペして貼ってみたりしてみたがどうしてもうまくいかなかった、しかし英語表記のエラー文をテストコードで使用するとテストがうまくいきます
日本語表記にしたのですから日本語表記のエラー文でテストができないと意味がありません、ですがどうしてもうまくいかないです。
皆様のお知恵を貸していただけると幸いにございます。

補足情報(FW/ツールのバージョンなど)

rubyバージョン _6.0.0_

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

追記

すいません。日本語訳を見落としていました。
gem 'rails-i18n'とconfig.i18n.default_locale = :jaで大丈夫なはずです。

下記コードであれば動くので試してみてください。

it 'itemが空だと出品できない' do
  item = Item.new(name:nil)
  item.valid?
  expect(item.errors.full_messages).to include('商品の名前を入力してください')
end

原因は、ご提示頂いたコードだと、@item.item = nilではなく、@item.name = nilが正解なはずです。


補足情報として、エラーメッセージのテストはあまり行わないことが多いかと思います。
理由として、何らかの理由でエラーメッセージを変更すると、テストをいちいち修正しなければならない、という問題が発生したりするからです。
そのためこちらの方法や下記などでテストするほうが望ましい気がします。

item = Item.new(name:nil)
expect(item).to_not be_valid

バリデーションエラーも翻訳して、日本語にしてはいかがでしょうか?

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/09/26 13:27

    バリデーションエラーも翻訳して、日本語にしてはとはどういうことでしょうか?
    自分なりにも調べてみたのですが言葉どうりに受け取るのであれば出品フォームでの入力ミスでクライアント側に見せるエラー文はしっかり日本語化できています。
    しかしテストコードで
    ```
    ~省略~

    context '商品出品できない時' do
    it 'itemが空だと出品できない' do
    @item.item = nil
    @item.valid?
    expect(@item.errors.full_messages).to include('商品の名前を入力してください')
    end

    ~省略~
    ```

    と記入すると
    expect(@item.errors.full_messages).to include('商品の名前を入力してください') の@item.errors.full_messagesの部分がなぜか英語表記でエラー文を出しているみたいで実際に表示される日本語表記のエラー文がマッチしない状態になってしまっているのです。
    今回日本語表記でエラー文を出しているのでそれでマッチさせたいのですがどうしてもうまくいかないのです。
    説明が足りなかったかもしれません申し訳ないです

    キャンセル

  • 2020/09/27 00:56

    ありがとうございました!
    二つ目に教えていただいたテストの仕方でうまくいきました!
    しかし上記に教えていただいた方法ではまだエラーが出てしまいました
    ```
    1) Item 商品出品 商品出品できない時 itemが空だと出品できない
    Failure/Error: expect(item.errors.full_messages).to include('商品の名前を入力してください')
    expected ["User must exist", "Item can't be blank", "Image can't be blank", "Text can't be blank", "Category c...ping origin は ” -- ” 以外を選択してください", "Arrival day can't be blank", "Arrival day は ” -- ” 以外を選択してください"] to include "商品の名前を入力してください"
    # ./spec/models/item_spec.rb:17:in `block (4 levels) in <top (required)>'

    Finished in 0.18859 seconds (files took 2.95 seconds to load)
    12 examples, 1 failure

    Failed examples:

    rspec ./spec/models/item_spec.rb:14 # Item 商品出品 商品出品できない時 itemが空だと出品できない
    ```

    このようなエラーです、見る限りやはりRspec側ではconfig.i18n.default_locale = :jaがきいていないみたいです疑問ですね。
    ですが何はともあれおかげさまで解決いたしました!
    本当にありがとうございますした!

    キャンセル

  • 2020/09/27 08:13

    エラーテストの書き方ですが、多くの場合、full_messagesを利用せず、下記のように書くのが一般的かと思います。
    expect(message.errors[:item]).to include("を入力してください")

    理由としては、できる限り小さい単位でテストをしないと、テスト内容が間違っているとき、どこが間違っているかわからなくなるためです。

    EverydayRailsにもテストのベストプラクティスの1つとして下記のように書かれています。
    ※「EverydayRails RspecによるRailsテスト入門」とはRailsテストのバイブル的な位置づけかと思います。
    もし持っていなければぜひ一度読んでみてください。

    example(itで始まる1行)一つにつき、結果を一つだけ期待している。私がfirst_name、last_name、emailのバリデーションをそれぞれ分けてテストしている点に注意してください。こうすれば、exampleが失敗したときに問題が起きたバリデーションを特定できます。原因調査のためにRSpecの出力結果を調べる必要はありません。少なくともそこまで細かく調べずに済むはずです。

    なのでテストの有効性と原因調査の精度を上げるために、.errorsでテストしてみるのはいかがでしょうか?

    キャンセル

  • 2020/09/27 13:56

    情報提供ありがとうございます!
    なるほどEverydayRailsですか持っていないです知りませんでした読んでみたいですね自分でも調べてみます。
    確かに範囲を限定した方が見極めやすいですよね、盲点でした。
    今一度教えてくださった方法でerrorsでテスト書き直してみます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.59%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る