9
votes

Un-singe patching une classe / méthode en rubis

J'essaie de tester un élément de code que j'ai écrit en rubis qui appelle fichier.open . Pour se moquer de it it, je monkeyypatched fichier.open sur les éléments suivants: xxx

Le problème est que j'utilise RCOV pour exécuter tout ce qui est utilisé .OPEN Pour écrire des informations sur la couverture du code, il obtient la version monkeyPatchetée au lieu de la vraie. Comment puis-je non-monkeyychatch cette méthode pour le revenir à sa méthode originale? J'ai essayé de jouer avec alias , mais sans être disponible jusqu'à présent.


0 commentaires

5 Réponses :


2
votes

fichier est juste une constante qui contient une instance de classe . Vous pouvez la définir à une classe temporaire qui répond à Ouvrir , puis restaurez l'original one: xxx


1 commentaires

Cela ne semble pas fonctionner au sein du test / de l'unité - il se plaint de redéfinir les constantes (fichier) et que cela ne va pas dans les méthodes (uniquement au niveau supérieur, ce qui m'empêche d'utiliser un test / unité).



2
votes

ou vous pouvez utiliser un cadre d'encombrement (comme RSPEC ou MOCHA) et supporter la méthode File.Open.

File.stub (: Ouvrir => "0 \ n")


2 commentaires

Je pouvais définitivement (j'avais précédemment utilisé à l'aide) mais je cherchais à utiliser Vanilla-Ruby pour faire ce travail.


@Chrisbunch en termes d'être pratique, c'est vraiment la solution correcte. Vous ne devriez pas être un peaming de singe, quelque chose de plus fondamental que l'ouverture de fichiers. Si vous n'essayez pas d'être pratique, êtes-vous simplement curieux? Aucun problème avec ça, mais je pense que les autres apprécieraient le savoir.



2
votes

Vous pouvez simplement le simple alias comme ceci: xxx

par exemple: xxx

Vous pouvez toujours accéder à la méthode Fichier d'origine.Open. via File.old_Open


Alternativement, vous pouvez essayer quelque chose comme ceci:

méthode de rubis - remplacement de la commande, puis revenir

http://blog.jayfields.com/2006/12/Ruby-alias-method-alternative.html


3 commentaires

C'est très proche de ce que je veux, mais je ne peux pas modifier RCOV, donc je ne peux donc pas le dire d'utiliser file.old_open . Je veux donc revenir old_open à Ouvrir une fois que mon test est terminé de sorte que RCOV le ramasse sans que je doive la modifier.


Je vois ... S'il vous plaît vérifier les pointeurs au bas de ma réponse


Cela a aidé beaucoup - merci! Cela ne fonctionne toujours pas avec RCOV, donc je devais travailler autour de lui une manière différente, mais les liens aident beaucoup pour l'avenir.



16
votes

Développement de la réponse de @ Tilo, utilisez à nouveau des alias pour annuler la correction de singe.

Exemple: P>

# Original definition
class Foo
  def one()
    1
  end
end

foo = Foo.new
foo.one

# Monkey patch to 2
class Foo
  alias old_one one
  def one()
    2
  end
end

foo.one

# Revert monkey patch
class Foo
  alias one old_one
end

foo.one


1 commentaires

Cela ne fonctionne donc pas avec RCOV (il ne voit toujours que l'ancienne méthode), mais comme la question était vraiment «juste une méthode un-singe patch une méthode», cela répond le mieux. Merci!



1
votes

La bonne façon de le faire est d'utiliser réellement un cadre d'encombrement comme Dan dit.

Par exemple, dans RSPEC, vous feriez: p>

> echo 'foo bar' > test.txt
> ruby isolated-patch.rb
stubbed open() returned: "0\n"
obviously wrong size of test.txt: "1\n"
size of test.txt: 8


0 commentaires