Rspec-Modelltests – aktueller_Benutzer im Modell
-
23-12-2019 - |
Frage
Ich verwende das Gem public_activity, um Aktivitäts-Feeds in meiner App zu generieren, und in meinem Modell verwende ich den current_user von devise, um den Eigentümer der Aktivität zu identifizieren.
class Question < ActiveRecord::Base
...
include PublicActivity::Model
tracked owner: ->(controller, model) { controller.current_user }
...
end
Mir ist klar, dass die Referenzierung auf current_user im Modell nicht die Norm ist, aber so ist es empfehle es zu tun.
Das funktioniert in der App einwandfrei, aber ich habe Probleme mit meinen Rspec-Tests, bei denen ich die folgende Fehlermeldung erhalte:
Failure/Error: expect(create(:question)).to be_valid
NoMethodError:
undefined method `current_user' for nil:NilClass
# ./app/models/question.rb:8:in `block in <class:Question>'
# ./spec/models/question_spec.rb:7:in `block (3 levels) in <top (required)>'
Der Test selbst ist typisch:
describe "Factory" do
it "has a valid factory" do
expect(create(:question)).to be_valid
end
end
Hier ist meine Fabrik:
FactoryGirl.define do
factory :question do
title { Faker::Lorem.characters(30) }
body { Faker::Lorem.characters(150) }
user_id { 1 }
tag_list { "test, respec" }
end
end
Wie bringe ich diese current_user-Methode in meinem Modell dazu, in meinen Tests zu funktionieren?
Lösung
Persönlich denke ich nicht, dass Sie darauf verweisen sollten controller
aus dem Inneren model
.Weil Sie a nicht instanziieren möchten controller
Objekt jedes Mal, wenn Sie auf das zugreifen möchten model
.
Beispielsweise möchten Sie möglicherweise auf die zugreifen model
von einem Hintergrundmitarbeiter:Wer ist dein current_user
und was ist euer controller
?
Dasselbe gilt auch für Ihre Testsuite.Sie möchten Ihre testen model
, nicht dein controller
.
Außerdem möchten Sie möglicherweise nicht immer die Aktivität verfolgen.
Ein besserer Ansatz besteht darin, die zu übergeben current_user
Objekt aus dem controller
.Ryan Bates hat ein schönes Beispiel in seinem Railscast über öffentliche Aktivitäten (siehe „Ausschließen von Aktionen“):
class Question < ActiveRecord::Base
include PublicActivity::Common
end
Und zwar für jede Aktivität, die Sie verfolgen möchten
@question.create_activity :create, owner: current_user
Andere Tipps
Sie müssen die RSpec-Helfer hinzufügen spec/support/devise.rb
:
RSpec.configure do |config|
config.include Devise::TestHelpers, :type => :controller
end
Weitere Informationen finden Sie hier Hier