12

Deviseのビューを実行rails g devise:viewsして生成しましたが、テストしたいと思います。

これは私が思いついたものです:

require 'spec_helper'

describe "devise/sessions/new" do
    before do
        render
    end

    it "renders the form to log in" do
        rendered.should have_selector("form", action: user_session_path, method: :post) do |form|

        end
    end
end

レンダリングステートメントの場合、それは私に与えますundefined local variable or method 'resource'グーグルした後、私は追加する必要があることがわかりました

@user.should_receive(:resource).and_return(User.new)

レンダリングステートメントの前に-しかし、それでも同じエラーが発生し、使用方法がよくわかりません。

私は何が間違っているのですか?ご協力いただきありがとうございます。

4

7 に答える 7

13

誰かが同じ問題に遭遇した場合の別の考え。私は、テストに合格できるようにするためだけにヘルパーにコードを追加することはあまり好きではなかったので、テストのbeforeブロックにこのコードを追加することになりました。

before do
  view.stub(:resource).and_return(User.new)
  view.stub(:resource_name).and_return(:user)
  view.stub(:devise_mapping).and_return(Devise.mappings[:user])
end
于 2013-11-12T14:18:48.133 に答える
6

そして、whaddyaは知っていますか?私は誰かが同様の問題を抱えているところでこの答えを見つけました。解決策は、アプリケーションヘルパーに次のコードを含めることです。

def resource_name
  :user
end

def resource
  @resource ||= User.new
end

def devise_mapping
  @devise_mapping ||= Devise.mappings[:user]
end

これが必要なのは、deviseがコントローラーで特定のヘルパーメソッドを使用しているためです。ただし、仕様からビューにアクセスすると、これらのヘルパーメソッドを使用できないため、テストが失敗します。これらのメソッドをアプリケーションヘルパー内に配置すると、仕様を含め、アプリケーション全体でこれらのメソッドにアクセスできるようになり、実際にテストに合格します。

于 2013-01-20T18:20:23.827 に答える
5

rspecには、定義されていないメソッドをスタブアウトできない構成がありますレール4を使用すると、標準的な動作になります。

# spec/spec_helper.rb
config.mock_with :rspec do |mocks|
  mocks.verify_partial_doubles = true
end

そのため、最も投票数の多い回答は、デバイスヘルパーでは機能しません。実際のヘルパーに変更verify_partial_doublesするか、使用してください。false

于 2015-07-23T18:16:09.903 に答える
4

Mike Foggのように、これらのビューの仕様を機能させるためだけにApplicationControllerにいくつかのメソッドを追加するというアイデアは好きではありませんでした。

rspecのインストールにspec/mixinsディレクトリがあることに気付いたので、次のようにしました。

# spec/mixins/devise_helpers.rb
module DeviseHelpers
  def resource_name
    :user
  end

  def resource
    @resource ||= User.new
  end

  def devise_mapping
    @devise_mapping ||= Devise.mappings[:user]
  end
end

次に、私の仕様に含めます。

# spec/views/devise/registrations/new.html.haml_spec.rb
require 'rails_helper'
include DeviseHelpers

describe 'devise/registrations/new.html.haml' do
  it 'has a login link for existing users' do
    render
    expect(rendered).to have_link('Log in')
  end
end

これで、これらのメソッドを、それらを必要とする任意の仕様に組み合わせることができます。

于 2015-07-04T17:22:14.153 に答える
3

@MikeFoggの解決策をやりたかったのですが、Punditを処理するために別のビュー仕様で同様のことを行いましたが、もちろん、@ChrisEdwardsが必要性に関して指摘した問題に直面しましたmocks.verify_partial_doubles = false

ただし、テストスイート全体でこれをオフにすることにはあまり興味がありませんでした。これは適切なチェックであり、「一般的に推奨」されており、Rspec4以降ではデフォルトになっています。

私は実際に最初にここに解決策を投稿し、ブロックの前後でRSpecを再構成しましたが、これを行うための本当に本当に簡単な方法に出くわしました。

  before(:each) do
    without_partial_double_verification do
      allow(view).to receive(:resource).and_return(Student.new)
      allow(view).to receive(:resource_name).and_return(:student)
      allow(view).to receive(:devise_mapping).and_return(Devise.mappings[:student])
    end
    # other before_each configuration here as needed
  end

これは2016年から存在しており、元々はと呼ばれwithout_verifying_partial_doublesていましたが、現在のに名前が変更されましたwithout_partial_double_verification。私が見ることができるどこにも文書化されていないようです。

于 2019-05-16T05:34:42.953 に答える
0

@ sixty4bitの答えこの答えをここで組み合わせて、私はこの解決策を思いつきました:

class DeviseHelpers < Module
  def initialize(resource_name, resource_class)
    @resource_name = resource_name
    @resource_class = resource_class
  end

  def extended(base)
    _resource_name = @resource_name
    _resource_class = @resource_class
    base.class_eval do
      define_method :resource_name do
        _resource_name
      end

      define_method :resource do
        @resource ||= _resource_class.new
      end

      define_method :devise_mapping do
        @devise_mapping ||= Devise.mappings[_resource_name]
      end
    end
  end

end

これにより、仕様の最上位で要求することにより、さまざまなリソースで使用できるようになります。

require 'support/devise_helpers'

そしてそれをこのように呼びます:

before do
  view.extend(DeviseHelpers.new(:customer, Customer))
end
于 2018-03-14T13:14:14.200 に答える
0

RSpec 4、Rails 6、およびDevise 4.7の場合、ここでの他の推奨事項に失敗したか、他のテストまたは製品コードへの影響を警戒していました。

allow(view).to receive(:current_user).and_return(user)

私の見解では、スペックは、他の構成を変更することなく、最終的に私のために機能したものでした。(最初に定義する必要がありますuser。)

ここ数年、基礎となる宝石/フレームワークに意味のある変更が加えられ、ここにある他のソリューションのいくつかが無効になる可能性はほとんどありません。Devise、RSpec、および/または関連するヘルパーを誤って構成した可能性がさらに高くなります。

current_userrspec / rails / example / view_example_group.rbに入力されていることを確認しましたが、nil中に戻ってきましrenderた。私はこのコメントをview_example_group.rbで見つけ、それに従いました:

        # The instance of `ActionView::Base` that is used to render the template.
        # Use this to stub methods _before_ calling `render`.
        #
        #     describe "widgets/new.html.erb" do
        #       it "shows all the widgets" do
        #         view.stub(:foo) { "foo" }
        #         render
        #         # ...
        #       end
        #     end
        def view
          _view
        end

https://github.com/rspec/rspec-rails/blob/main/lib/rspec/rails/example/view_example_group.rb

stub構文は非推奨ですが、view.stub(:current_user) { user }(今のところ)機能します。

于 2020-09-06T14:15:50.867 に答える