2011-07-21 7 views
3

J'ai plusieurs tests rspec qui utilisent Factory_girl. Il est utilisé sur MongoDB avec MongoId dans une application Rails 3.Comment éviter la persistance d'un objet Factory Girl

Quelque part le long de la ligne, je teste des valeurs non valides: attendre des erreurs de validation. Après cela, chaque fois que j'appelle Factory(:user), il échoue, en raison d'erreurs de validation. Je m'attendrais à un objet entièrement nouveau et propre, quand j'appelle Factory (: user), pas un objet réutilisé, battu.

Le code ci-dessous illustre le * user_spec.rb * en ajoutant des éléments non valides aux «rôles». Le modèle utilisateur marque correctement l'enregistrement comme non valide.

Un peu plus loin dans les spécifications, un * sidebar_helper_spec.rb * doit instancier un @user, et là il échoue, me disant que le rôle invalide "foo" est là. Mais vous pouvez clairement voir que ce rôle n'est pas présent dans la factory.rb.

Est-ce que ce comportement est attendu? Puis-je basculer la persistance (ou la mise en cache?) Avec une option de configuration?

## models/user_spec.rb 

require 'spec_helper' 
describe User do 
    describe 'roles' do 
    before(:each) do 
     @user = Factory.build(:user) 
    end 
    it 'should require a role' do 
     @user.roles = nil 
     @user.should_not be_valid 
    end 
    it 'should allow one role from set of defined roles' do 
     #@user.roles is preset in factory with "jobseeker" 
     @user.should be_valid 
    end 
    it 'should reject undefined roles' do 
     @user.roles << "foo" 
     @user.should_not be_valid 
    end 
    it 'should allow multiple roles' do 
     @user.roles = ["banned", "jobseeker"] 
     @user.should be_valid 
    end 
    end 
end 

## helpers/sidebar_helper_spec.rb 

require 'spec_helper' 
describe SidebarHelper do 
    before(:each) do 
    @user = Factory.create(:user) #fails with Mongoid::Errors::Validations: Validation failed - Roles foo is an invalid role. 
    @profile = Factory.create(:profile) 
    end 

    # Has many specs, but all Fail on error in the before(:each) 
end 

## Actual factory.rb 

Factory.define :user do |f| 
    f.password 'mischief managed' 
    f.email  '[email protected]' 
    f.roles  ['jobseeker'] 
end 
Factory.define :employer do |f| 
    f.password 'butterscotch' 
    f.email  '[email protected]' 
    f.roles  ['employer'] 
end 

Factory.define :profile do |f| 
    f.available true 
    f.sync false 
end 

Répondre

1

= crée une nouvelle gamme ["banned", "jobseeker"] et ensembles à @user.roles: (!-À-dire modifie le tableau existant)

# should allow multiple roles 
@user.roles = ["banned", "jobseeker"] 

MAIS <<ajoute"foo" au tableau déjà existant:

# should reject undefined roles 
@user.roles << "foo" 

FactoryGirl est et non en réutilisant le même objet utilisateur, mais en réutilisant le même attribut roles. Il suffit de changer le tableau roles à créer dynamiquement à chaque fois dans l'usine:

Factory.define :user do |f| 
    ... 
    f.roles  { ['jobseeker'] } 
end 
Factory.define :employer do |f| 
    ... 
    f.roles  { ['employer'] } 
end 

Soit cela, OU éviter d'utiliser << ou toute autre méthode qui change un tableau/variable existante, et utiliser à la place = qui utilise une nouvelle objet. par exemple.

# should reject undefined roles 
@user.roles = [ "foo" ] 
Questions connexes