Dans mon application, j'ai le code suivant :
File.open "filename", "w" do |file|
file.write("text")
end
Je veux tester ce code via RSpec. Quelles sont les meilleures pratiques pour le faire ?
Dans mon application, j'ai le code suivant :
File.open "filename", "w" do |file|
file.write("text")
end
Je veux tester ce code via RSpec. Quelles sont les meilleures pratiques pour le faire ?
Je suggère d'utiliser StringIO
pour cela et s'assurer que votre SUT accepte un flux vers lequel écrire au lieu d'un nom de fichier. De cette façon, différents fichiers ou sorties peuvent être utilisés (plus réutilisable), y compris la chaîne IO (bon pour les tests)
Ainsi, dans votre code de test (en supposant que votre instance SUT est sutObject
et le sérialiseur est nommé writeStuffTo
:
testIO = StringIO.new
sutObject.writeStuffTo testIO
testIO.string.should == "Hello, world!"
String IO se comporte comme un fichier ouvert. Donc si le code peut déjà fonctionner avec un objet File, il fonctionnera avec StringIO.
Bonne réponse, je sais que ce n'était pas demandé mais cela aurait été parfait si elle avait inclus l'exemple du partenaire "lu" également.
Comment modifier le code pour utiliser String.IO ? Il semble que le code résultant sera beaucoup plus laid, juste pour que les tests soient plus faciles ?
Pour des entrées/sorties très simples, vous pouvez simplement simuler File. Donc, donné :
def foo
File.open "filename", "w" do |file|
file.write("text")
end
end
alors :
describe "foo" do
it "should create 'filename' and put 'text' in it" do
file = mock('file')
File.should_receive(:open).with("filename", "w").and_yield(file)
file.should_receive(:write).with("text")
foo
end
end
Cependant, cette approche tombe à plat en présence de lectures/écritures multiples : de simples refactorings qui ne changent pas l'état final du fichier peuvent provoquer la rupture du test. Dans ce cas (et éventuellement dans tous les cas), vous devriez préférer la réponse de @Danny Staple.
Voici comment simuler un fichier (avec rspec 3.4), afin de pouvoir écrire dans un tampon et vérifier son contenu ultérieurement :
it 'How to mock File.open for write with rspec 3.4' do
@buffer = StringIO.new()
@filename = "somefile.txt"
@content = "the content fo the file"
allow(File).to receive(:open).with(@filename,'w').and_yield( @buffer )
# call the function that writes to the file
File.open(@filename, 'w') {|f| f.write(@content)}
# reading the buffer and checking its content.
expect(@buffer.string).to eq(@content)
end
Vous pouvez utiliser fauxfs .
Il supprime le système de fichiers et crée des fichiers en mémoire.
Vous vérifiez avec
File.exists? "filename"
si le fichier a été créé.
Vous pouvez aussi simplement le lire avec
File.open
et de lancer une espérance sur son contenu.
Notez que FakeFS échoue avec Rspec (tant Rspec 2 que Rspec 3) - github.com/fakefs/fakefs/issues/215
Pour quelqu'un comme moi qui a besoin de modifier plusieurs fichiers dans plusieurs répertoires (par exemple le générateur pour Rails), j'utilise le dossier temp.
Dir.mktmpdir do |dir|
Dir.chdir(dir) do
# Generate a clean Rails folder
Rails::Generators::AppGenerator.start ['foo', '--skip-bundle']
File.open(File.join(dir, 'foo.txt'), 'w') {|f| f.write("write your stuff here") }
expect(File.exist?(File.join(dir, 'foo.txt'))).to eq(true)
end
end
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
0 votes
@Wayne Je me demande comment vous allez procéder avec testunit Voir [cette question][1][1] : stackoverflow.com/questions/11619884/