В моем приложении у меня такой код:
File.open "filename", "w" do |file|
file.write("text")
end
Я хочу протестировать этот код через rspec. Каковы наилучшие методы для этого?
В моем приложении у меня такой код:
File.open "filename", "w" do |file|
file.write("text")
end
Я хочу протестировать этот код через rspec. Каковы наилучшие методы для этого?
Я бы предложил использовать StringIO
для этого и убедиться, что ваш SUT принимает поток для записи вместо имени файла. Таким образом, можно использовать различные файлы или выходы (более многократно используемые), включая строку IO (хорошо для тестирования)
Итак, в вашем тестовом коде (если ваш экземпляр SUT равен sutObject
, а сериализатор имеет имя writeStuffTo
:
testIO = StringIO.new
sutObject.writeStuffTo testIO
testIO.string.should == "Hello, world!"
Строка IO ведет себя как открытый файл. Поэтому, если код уже может работать с объектом File, он будет работать с StringIO.
Для очень простого ввода/вывода вы можете просто высмеять файл. Итак, учитывая:
def foo
File.open "filename", "w" do |file|
file.write("text")
end
end
то
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
Однако этот подход падает при наличии нескольких операций чтения/записи: простые рефакторинги, которые не изменяют конечное состояние файла, могут привести к разрыву теста. В этом случае (и, возможно, в любом случае) вы должны предпочесть ответ @Danny Staple.
Вы можете использовать fakefs.
Он заглушает файловую систему и создает файлы в памяти
Вы проверяете с помощью
File.exists? "filename"
если файл был создан.
Вы также можете просто прочитать его с помощью
File.open
и запустите ожидание его содержимого.
Вот как издеваться над файлом (с rspec 3.4), поэтому вы можете писать в буфер и позже проверять его содержимое:
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