2010-02-23 17 views
0

J'utilise RR pour moquer et stubbing dans RSpec, et j'ai rencontré une situation où je voudrais remplacer une méthode d'une super classe d'un contrôleur qui définit certaines variables d'instance. Je peux déterminer comment terminer l'appel de la méthode et si je débogue, je peux voir que mon bloc stubbed est appelé, mais je ne peux pas obtenir les variables d'instance dans le bloc pour se propager dans la classe que je suis en train de tester.Comment est-ce que je peux stub un before_filter dans une super classe dans Rails?

Juste pour le décomposer:

class A < ApplicationController 
    before_filter :bogglesnap 

    def bogglesnap 
    @instancevar = "totally boggled" 
    end 
end 

class B < A 
    def do_something_with_instance 
    if @instancevar 
     .... 
    else 
     .... 
    end 
    end 
end 

C'est la configuration de base, et donc ensuite dans mes tests pour contrôleur B Je voudrais bouchonner la méthode de bogglesnap de A à mettre @instancevar à quelque chose que je vouloir. Je ne peux pas comprendre comment le faire.

J'ai essayé de stubbing de instance_of de RR et juste stubbing la définition du contrôleur:

stub.instance_of(A).bogglensap { @instancevar = "known value" } 
stub(controller).bogglesnap { @instancevar = "known value" } 

mais aucun de ceux-ci semblent fonctionner, eh bien, ils ne fonctionnent pas :)

Quelqu'un at-il des pointeurs sur la façon dont vous devriez être en mesure d'enchaîner cette méthode appelez-vous et lui faire définir des variables d'instance? Je suppose que cela a à voir avec le contexte dans lequel le bloc est exécuté, mais j'espère que quelqu'un a déjà traversé quelque chose comme ça avant.

Merci

Répondre

2

Vous pouvez utiliser la méthode instance_variable_set en faisant appel à l'instance d'objet et le mettre à tout ce que vous voulez, comme si

controller.instance_variable_set("@instancevar", "known value") 

et même, si jamais vous voulez récupérer la valeur d'un variable d'instance dans votre spec ou debug ou faire quelque chose d'autre de l'extérieur de la classe, vous pouvez alors obtenir la valeur en faisant

controller.instance_variable_get("@instancevar") 

Rappelez-vous, instance_variable_set et instance_variable_get méthodes sont disponibles non seulement pour les contrôleurs mais tous les objets tels qu'ils sont fournis par ruby. En fait, ces deux méthodes jouent un rôle important dans la magie des rails :)

+0

Je connaissais la variable d'instance et la programmation dynamique qu'offre ruby, je n'avais juste pas pensé à l'utiliser ... merci pour le prod cérébral! :) Je viens de l'essayer et j'ai confirmé que cela fonctionne. – ozzyaaron