Rspec: cómo probar las operaciones y el contenido del archivo
En mi aplicación tengo dicho código:
File.open "filename", "w" do |file|
file.write("text")
end
Quiero probar este código a través de rspec. ¿Cuáles son las mejores prácticas para hacer esto?
5 answers
Sugeriría usar StringIO
para esto y asegurarse de que su SUT acepta una secuencia para escribir en lugar de un nombre de archivo. De esa manera, se pueden usar diferentes archivos o salidas (más reutilizables), incluida la cadena IO (buena para probar)
Así que en su código de prueba (suponiendo que su instancia SUT es sutObject
y el serializador se llama writeStuffTo
:
testIO = StringIO.new
sutObject.writeStuffTo testIO
testIO.string.should == "Hello, world!"
String IO se comporta como un archivo abierto. Así que si el código ya puede trabajar con un objeto File, funcionará con StringIO.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-10 10:25:04
Para e/s muy simples, solo puede simular el archivo. Así, dado:
def foo
File.open "filename", "w" do |file|
file.write("text")
end
end
Entonces:
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
Sin embargo, este enfoque cae plano en presencia de múltiples lecturas/escrituras: refactorizaciones simples que no cambian el estado final del archivo pueden causar que la prueba se rompa. En ese caso (y posiblemente en cualquier caso) deberías preferir la respuesta de @Danny Staple.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-02 05:25:08
Puede usar fakefs.
Extrae el sistema de archivos y crea archivos en la memoria
Se comprueba con
File.exists? "filename"
Si se creó el archivo.
También puedes leerlo con
File.open
Y ejecutar la expectativa sobre su contenido.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-07 20:08:37
Esta es la forma de simular el archivo (con rspec 3.4), para que pueda escribir en un búfer y comprobar su contenido más tarde:
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-27 10:32:16
Para alguien como yo que necesita modificar varios archivos en varios directorios (por ejemplo, generator for Rails), uso la carpeta 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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-02 12:47:41