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

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

ただいまの
回答率

87.35%

Rspecのテストを実行すると「raise WrongScopeError, "`#{name}` is not available from within an exam」というエラーになる

解決済

回答 1

投稿 編集

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

score 590

現在以下を参考にRails APIを作成し、Rspecでテストをしようとしています。
Railsで超簡単API
【Rails】APIテストの書き方

APIを作り終えて、Rspecの環境構築をし、テストを実装したので、bundle exec rspecでテスト実行すると以下のようなエラーが出ました。

F

Failures:

  1) PostAPI 全てのポストを取得する
     Failure/Error:
       raise WrongScopeError,
             "`#{name}` is not available from within an example (e.g. an " \
             "`it` block) or from constructs that run in the scope of an " \
             "example (e.g. `before`, `let`, etc). It is only available " \
             "on an example group (e.g. a `describe` or `context` block)."

       `name` is not available from within an example (e.g. an `it` block) or from constructs that run in the scope of an example (e.g. `before`, `let`, etc). It is only available on an example group (e.g. a `describe` or `context` block).

(省略)

Finished in 0.00662 seconds (files took 2.44 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/request/api/v1/posts_spec.rb:5 # PostAPI 全てのポストを取得する

これを解決するにはどうしたらいいでしょうか?
調べているのですが、なかなか解決できずにいます。
設定周りなのか、コードなのか、プロダクトコードが認識できていないのか、なにかライブラリが読み込めていないのか、、、いろんな予想を立てて調べています。

もしアドバイスいただける方がいらっしゃいましたらお願いいたします。

以下のようなフォルダ構成です
イメージ説明

以下のようなコードです。
↓posts_spec.rb

require 'rails_helper'
# [Rails API Testing Best Practices] (https://matthewlehner.net/rails-api-testing-guidelines)

describe 'PostAPI' do
  it '全てのポストを取得する' do
    post = create(:post, title: 'test-title')

    get "/api/v1/posts/#{post.id}"
    json = JSON.parse(response.body)

    # リクエスト成功を表す200が返ってきたか確認する。
    expect(response.status).to eq(200)

    # 要求した特定のポストのみ取得した事を確認する
    expect(json['data']['title']).to eq(post.title)
  end
end

PostmanでAPIのCRUDは実施確認済みです。(プロダクトコードは参考サイトと同様です。)

Gemfileは以下です。(「★追加」とコメントしているところがテストコード実装時に追加したものです。)

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.7.1'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails', branch: 'main'
gem 'rails', '~> 6.1.2', '>= 6.1.2.1'
# Use sqlite3 as the database for Active Record
gem 'sqlite3', '~> 1.4'
# Use Puma as the app server
gem 'puma', '~> 5.0'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
# gem 'jbuilder', '~> 2.7'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Active Storage variant
# gem 'image_processing', '~> 1.2'

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.4', require: false

# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
# gem 'rack-cors'

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'factory_bot_rails' #★追加
  gem 'rspec-rails', '~> 3.9.1' #★追加
end

group :development do
  gem 'listen', '~> 3.3'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

追記

試したこと

・「rspec "#{name} is not available from within an example」で検索
結果、以下のサイトを確認しましたがピンとこず解決に至っていません。
https://stackoverflow.com/questions/45439673/rspec-mocking-name-not-available-from-within-an-example-group
https://qiita.com/opiyo_taku/items/6364adf27102d30f0e6d

・変数のスコープ絡みなのかな。といった観点でも調査。

・テストコードを中身がない状態や必ずtrueとなる状態にして実施→同じエラーが出る

require 'rails_helper'

describe 'PostAPI' do
  it '全てのポストを取得する' do
    expect(1).to eq(1) #これを消しても同じエラー
  end
end

追記2
▼こちらに現在うまくRspecが起動できないプロジェクトを置きました。(blogプロジェクト)
https://github.com/k49977/railsAPI/tree/master/blog
「rails s」でサーバー起動し、
exec rspec spec/request/api/v1/posts_spec.rbでテストを実行すると現状のエラーになります。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • k499778

    2021/02/22 23:08

    上記のように出ました。
    私の環境では「ruby -v」すると
    「ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin17]」となっているので、Gemfileもそれに合わせる必要がありそうです

    キャンセル

  • k499778

    2021/02/22 23:08

    はじめてRspecを触るので、結構初歩的なミスかもしれません。。。

    キャンセル

  • k499778

    2021/02/22 23:14

    rubyやrails自体もまだあまり慣れていない状態です。

    キャンセル

回答 1

check解決した方法

+1

一応解決できましたが、原因を整理できていないので行ったことを記載します。

①少しまだまだgemやbundle絡みの扱い方も怪しいのですが、
bundle updateやbundle cleanを行い、インストールされているgemをおそらくgemfileに書かれている通りに明示的に行いました。

②次に「undefined method "create"」「"undefined method 'get'"」と怒られたので、参考リンクより「FactoryBot.create」「, type: :request」とすることで解決できました。

↓spec/request/api/v1/posts_spec.rb

require 'rails_helper'

describe 'PostAPI', type: :request do
  it '全てのポストを取得する' do
    post = FactoryBot.create(:post, title: 'test-title')

    get "/api/v1/posts/#{post.id}"
    json = JSON.parse(response.body)

    # リクエスト成功を表す200が返ってきたか確認する。
    expect(response.status).to eq(200)

    # 要求した特定のポストのみ取得した事を確認する
    expect(json['data']['title']).to eq(post.title)
  end
end

参考:
GETリクエストをするspecを実行して"undefined method get"と怒られた時は
Rspec - NoMethodError: undefined method `create' でエラーとなってしまいFactoryが適切に動かない

イメージ説明

もう少しヘルパーを使えばスッキリ書けそうな気もするし、元々参考にしていたサイトとコードが違うことも気になるので、もう少し数を打って、理解を深めたいと思います。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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

  • トップ
  • Rubyに関する質問
  • Rspecのテストを実行すると「raise WrongScopeError, "`#{name}` is not available from within an exam」というエラーになる