2009-12-14 5 views
1

J'ai une classe qui effectue plusieurs opérations de base de données, et je veux écrire un test unitaire qui vérifie que toutes ces opérations sont effectuées dans une transaction. Qu'est-ce qu'une belle façon de faire?Quelle est la bonne façon de vérifier dans un test unitaire qu'une transaction ActiveRecord est utilisée?

Voici quelques exemples de code illustrant la classe que je teste:

class StructureUpdater 
    def initialize(structure) 
    @structure = structure 
    end 

    def update_structure 
    SeAccount.transaction do 
     delete_existing_statistics 
     delete_existing_structure 
     add_campaigns 
     # ... etc 
    end 
    end 

    private 

    def delete_existing_statistics 
    # ... 
    end 

    def delete_existing_structure 
    # ... 
    end 

    def add_campaigns 
    # ... 
    end 
end 

Répondre

0

Rspec vous permet d'affirmer que les données ont changé dans le cadre d'un bloc particulier.

it "should delete existing statistics" do 
    lambda do 
     @structure_updater.update_structure 
    end.should change(SeAccount, :count).by(3) 
end 

... ou quelque fonction de ce que votre schéma ressemble, etc. Je ne sais pas ce qui se passe dans delete_existing_statistics modifier si exactement la clause de changement en conséquence.

EDIT: Je n'ai pas compris la question au début, mes excuses. Vous pouvez essayer de faire valoir les éléments suivants pour vous assurer que ces appels se produisent dans un ordre donné (encore une fois, en utilisant RSpec):

EDIT: Vous ne pouvez pas affirmer une attente contre une transaction dans un test qui a des attentes pour les appels dans cette transaction. Le plus proche que je pouvais venir avec de la manchette est:

describe StructureUpdater do 
    before(:each) do 
     @structure_updater = StructureUpdater.new(Structure.new) 
    end 

    it "should update the model within a Transaction" do 
     SeAccount.should_receive(:transaction) 
     @structure_updater.update_structure 
    end 

    it "should do these other things" do 
     @structure_updater.should_receive(:delete_existing_statistics).ordered 
     @structure_updater.should_receive(:delete_existing_structure).ordered 
     @structure_updater.should_receive(:add_campaigns).ordered 
     @structure_updater.update_structure 
    end 
end 

UN ESSAI PLUS: Une autre astuce mineure serait de forcer l'un des appels de méthode plus tard dans le bloc de transaction à soulever, et affirmer que rien n'a changé la DB. Par exemple, si Statistic est un modèle et que delete_existing_statistics change le nombre de statistiques dans la base de données, vous pouvez savoir qu'un appel s'est produit dans une transaction si une exception renvoyée plus tard dans la transaction annule cette modification. Quelque chose comme:

it "should happen in a transaction" do 
    @structure_updater.stub!(:add_campaigns).and_raise 
    lambda {@structure_updater.update_structure}.should_not change(Statistic, :count) 
end 
+0

Je ne sais pas comment cela va aider à vérifier que les opérations ont été effectuées à l'intérieur d'une transaction –

+0

Je pense que je comprends maintenant - voir modifier. –

+0

Désolé pour le malentendu. J'ai supposé que vous vouliez dire que vous vouliez être sûr que * ces appels * se sont produits dans la transaction. Vous vouliez dire que vous vouliez être sûr que ces appels se produisaient * dans le cadre d'une transaction *. –

Questions connexes