2017-09-05 2 views
0

Ich schreibe einige Tests mit FactoryGirl und Rspec.Variable zwischen mehreren Kontexten mit Rspec übergeben

spec/Fabriken/students.rb:

FactoryGirl.define do 
    factory :student do 
    end 

    factory :student_with_profile_and_identity, class: 'Student' do 
    after(:create) do |student| 
     create(:profile, profileable: student) 
     create(:student_identity, student: student) 
    end 
    end 
end 

spec/Fabriken/profiles.rb:

FactoryGirl.define do 
    factory :profile do 
    birthday { Faker::Date.birthday(15, 150) } 
    sequence(:email) { |i| "profile_#{i}@email.com" } 
    first_name { Faker::Name.first_name } 
    last_name { Faker::Name.first_name } 
    password { Faker::Internet.password(6, 72, true, true) } 
    end 
end 

spec/Fabriken/student_identities.rb:

FactoryGirl.define do 
    factory :student_identity do 
    provider { ['facebook.com', 'google.com', 'twitter.com'].sample } 
    uid { Faker::Number.number(10) } 
    end 
end 

spec/Anfragen/authorizations_spec.rb:

require 'rails_helper' 

RSpec.describe 'Authorizations', type: :request do 
    describe 'POST /v1/authorizations/sign_in' do 
    let!(:student) { create(:student_with_profile_and_identity) } 

    context 'when the request is valid' do 
     subject do 
     post '/v1/authorizations/sign_in', 
      params: credentials 
     end 

     context "user signs up via social network" do 
     let(:credentials) do 
      { 
      authorization: { 
       student: { 
       profile_attributes: { 
        email: student.profile.email 
       }, 
       student_identities_attributes: { 
        provider: student.student_identities[0].provider, 
        uid: student.student_identities[0].uid 
       } 
       } 
      } 
      } 
     end 

     it 'returns an authentication token' do 
      subject 
      p "1 student.profile.inspect #{student.profile.inspect}" 
      expect(json['token']).to(be_present) 
     end 
     end 

     context 'when the user has already an account' do 
     let(:credentials) do 
      { 
      authorization: { 
       email: student.profile.email, 
       password: student.profile.password 
      } 
      } 
     end 

     it 'returns an authentication token' do 
      p "2 student.profile.inspect #{student.profile.inspect}" 
      subject 
      expect(json['token']).to(be_present) 
     end 
     end 
    end 
    end 
end 

Fast alle Tests vorbei sind ... ist das Problem, dass:

Es ist einen neuen Student in jedem Kontext zu schaffen. Ich würde erwarten, dass die let!(:student) { ... } so etwas wie "singleton", mit anderen Worten, sobald es hier erstellt/definiert ist let!(:student) { create(:student_with_profile_and_identity) } wird es nicht mehr aufgerufen werden.

Ex: die Protokolle sind wie folgt aus:

"1 student.profile.inspect #<Profile id: 1, email: \"[email protected]\", profileable_type: \"Student\", profileable_id: 1>" 

"2 student.profile.inspect #<Profile id: 2, email: \"[email protected]\", profileable_type: \"Student\", profileable_id: 2>" 

Während ich die Instanzen gleich sein erwarten würde.

Fehle ich etwas?

Antwort

0

In RSpec, let and let! sind die gleiche Sache, mit der Ausnahme, dass let faul ist und let! ist eifrig:

Verwenden let eine memoized Hilfsmethode zu definieren. Der Wert wird im selben Beispiel, aber nicht in mehreren Beispielen über mehrere Aufrufe hinweg zwischengespeichert.

Beachten Sie, dass let lazy-evaluated ist: Es wird erst beim ersten Aufruf der von ihm definierten Methode ausgewertet. Sie können let! verwenden, um den Aufruf der Methode vor jedem Beispiel zu erzwingen.

Wenn Sie etwas wollen, durch alle Beispiele beharren, können Sie ein before hook verwenden ... before(:context) klingt wie es sein könnte, was Sie wollen. Sie könnten eine Hilfsmethode zur Einrichtung der Lage sein, die in einem before Block memoizes, zu vermeiden überall eine Instanzvariable verwenden (pro this comment):

def student 
    @student ||= create(:student_with_profile_and_identity) 
end 

before(:context) do 
    student # force student creation 
end 
Verwandte Themen