Frage

Ich versuche, meine Controller create Aktion zu testen. Ich verwende Devise für die Authentifizierung und haben die before_filter Methode den Zugriff auf die create Aktion eingeloggten verwendet Benutzer. Hier ist der relevante Teil meiner Controller.

class RawDataSetsController < ApplicationController
  before_filter :authenticate_user!, :except => [:show, :index, :download]

  def create
    @raw_data_set = current_user.raw_data_sets.build(params[:raw_data_set])
    if @raw_data_set.save
      redirect_to @raw_data_set
    else
      render "new"
    end
  end
end

In meinem Testfall möchte ich sicherstellen, dass ein angemeldeter Benutzer eine RawDataSet erstellen können. Ich denke, dass ich einen authentifizierten Benutzer gemäß den Anweisungen auf dieser Blogeintrag verspottet .

require 'spec_helper'
describe RawDataSetsController do

  include Devise::TestHelpers

  def mock_users(stubs={})
    @user ||= mock_model(User, stubs).as_null_object
  end

  def log_in_test_user
    attr = { :username => "Foobar", :email => "doineedit@foobar.com" }
    #mock up an authentication in warden as per http://www.michaelharrison.ws/weblog/?p=349
    request.env['warden'] = mock(Warden, :authenticate => mock_users(attr),
                                         :authenticate! => mock_users(attr),
                                         :authenticate? => mock_users(attr))
  end

  before do
    @rds = Factory(:raw_data_set)
  end

  describe "POST 'create'" do

    before do
      @attr = { 
        :organism_name => "Beef Jerky",
        :mass_spec_type => "My Stomach",
      }
    end

    describe "logged in user" do
      it "should create a raw_data_set when the user is logged in" do
        log_in_test_user
        lambda do
          post :create, :raw_data_set => @attr
        end.should change(RawDataSet, :count).by(1)
      end
    end
  end
end

Mit diesem Testfall Laufen verursacht die folgenden Fehler:

1) RawDataSetsController POST 'create' logged in user should create a raw_data_set when the user is logged in
 Failure/Error: post :create, :raw_data_set => @attr
 undefined method `user_url' for #<RawDataSetsController:0x0000010175af88>
 # ./app/controllers/raw_data_sets_controller.rb:7:in `create'

Ich bin von diesem Fehler verwirrt. Bei mehr Kontrolle ist @raw_data_set nicht eine Instanz der RawDataSet Modellklasse, sondern ein Benutzer? Dies ist, wie es aussieht, wenn ich p @raw_data_set

#<User:0x807a06a4 @name="User_1002">

Was zum Teufel ist hier los? Was mache ich falsch? Wie kann ich teste die Wirkung auf meinem Controller mit einem authentifizierten Benutzer erstellen?

War es hilfreich?

Lösung

Bearbeiten (total falsch erster Versuch entfernt)

Beim as_null_object sagt im Wesentlichen der mock alle Nachrichten zu akzeptieren, die nicht gerodet werden und zurück selbst gerade. Also, wenn Sie anrufen

current_user.raw_data_sets.build(params[:raw_data_set])

, die normalerweise einen neuen RawDataSet zu current_user zugeordnet zurückkehren würde, Sie current_user wieder stattdessen bekommen.

Also, wenn Sie, um die Anrufweiterleitung versuchen, in @raw_data_set vorbei, ich ist es, die Mock statt einer RawDataSet Instanz zu übergeben, so dass der verirrten Aufruf user_url.

Ich denke, die Art und Weise, dies zu umgehen ist nur einen echten Benutzer (oder eine Factory) und Stummel aus der Devise Methoden darauf. Also Ihre mock_users wird (zum Beispiel):

  def mock_users(stubs={})
    @user = User.create(stubs)
  end

Jetzt current_user wird die Build tatsächlich tun und durch die Assoziation speichern.

Puristen werden Ihnen sagen, zu verspotten und Stub alles, bis Sie blau im Gesicht. Schraube, dass - Sie haben bessere Dinge zu tun. :)

Der andere Weg, um diesen Ansatz zu testen, ob die Build-Nachricht ohne Überprüfung empfangen wird, ob das gelungen retten. Vermutlich Ihre Modelltests überprüfen, ob durch den Verein Speicher funktioniert - warum Test erneut im Controller

Andere Tipps

Wenn Sie das Verhalten von Sign-in etwas Bestimmtes zum Beispiel ändern tun, können Sie von devise Controller erben und sie überschreiben. Sie können die Anweisung von hier folgen https://github.com/plataformatec/devise die Konfiguration von Controllern.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top