2008-09-16 8 views
3

Je suis un développeur Java jouant avec Ruby, et je l'adore. J'ai compris que grâce aux installations de métaprogrammation de Ruby, mes tests unitaires deviennent beaucoup plus propres et je n'ai pas besoin de mauvais cadres de moquerie. J'ai une classe qui a besoin des services de la classe File et dans mon test je ne veux pas toucher mon vrai système de fichiers. En Java, j'utiliserais un système de fichiers virtuel pour que les «coutures» soient plus faciles à transmettre, mais dans Ruby, c'est évidemment trop. Ce que j'arrive semble déjà vraiment sympa par rapport au monde Java. Dans ma classe en cours de test, j'ai un paramètre constructeur en option:Constructeurs moqueurs dans Ruby

def initialize(file_class=File) 

Quand je dois ouvrir des fichiers dans ma classe, je peux alors faire ceci:

@file_class.open(filename) 

Et l'appel est soit le vrai File-class, ou dans le cas de mon test d'unité, il va à une fausse-classe qui ne touche pas le système de fichiers. Je sais qu'il doit y avoir une meilleure façon de le faire avec la métaprogrammation?

Répondre

11

Mocha (http://mocha.rubyforge.org/) est une très bonne bibliothèque de moqueurs pour ruby. En fonction de ce que vous voulez vraiment tester (par exemple, si vous voulez juste falsifier l'appel File.new pour éviter la dépendance du système de fichiers ou si vous voulez vérifier que les bons arguments sont passés dans File.new), vous pouvez faire Quelque chose comme ceci:

 

require 'mocha' 

mock_file_obj = mock("My Mock File") do 
    stubs(:some_instance_method).returns("foo") 
end 

File.stubs(:new).with(is_a(String)).returns(mock_file_obj) 
 
+0

Oui, je préfère ne pas simplement utiliser une bibliothèque se moquant du tout. En as-tu vraiment besoin en Ruby? – auramo

+3

Je ne vois pas le besoin d'avoir une aversion pour une bibliothèque moqueuse. Mocha est juste en train de faire la métaprogrammation pour vous (c'est-à-dire les méthodes de remplacement, etc.) que vous demandez de faire manuellement. –

+0

@BrianPhillips Comment vérifiez-vous que les méthodes stubbed ont été appelées –

1

Dans le cas que vous avez décrit, je dirais que ce que vous faites semble bien. Je sais que c'est une technique que James Mead (l'auteur de Moka) a préconisée. Il n'y a pas besoin de faire de la métaprogrammation juste pour le plaisir. Here's what James has to say about it (et une longue liste d'autres techniques que vous pourriez essayer)

1

Ceci est un défi particulièrement difficile pour moi. Avec l'aide que j'ai reçue sur this question, et un peu de travail en mon nom, voici la solution à laquelle je suis arrivé.

# lib/real_thing.rb 
class RealThing 
    def initialize a, b, c 
    # ... 
    end 
end 

# test/test_real_thing.rb 
class TestRealThing < MiniTest::Unit::TestCase 

    class Fake < RealThing; end 

    def test_real_thing_initializer 
    fake = mock() 
    Fake.expects(:new).with(1, 2, 3).returns(fake) 
    assert_equal fake, Fake.new(1, 2, 3) 
    end 

end