#ruby #rspec #rspec-mocks
#ruby #rspec #rspec-издевается
Вопрос:
Я хочу знать, одобрено ли это решение сообществом mocking object в ruby. Если нет, пожалуйста, опишите, почему и как я могу улучшить дизайн кода или, возможно, протестировать.
Рассмотрим, что у меня есть следующий код.
lib/config_loader.rb
class ConfigLoader
HOME_DIR = '~/my/home_dir'.freeze
...
def load(path)
path = File.expand_path(path)
if File.exist?(path)
File.read(path)
else
File.read(HOME_DIR)
end
end
end
При тестировании я на самом деле не хочу, чтобы что-либо создавалось в соответствии path
с тем, что я определил в переменной, поэтому я просто хочу издеваться над этим поведением
spec/lib/config_loader_spec.rb
RSpec.describe ConfigLoader do
describe '.load' do
subject { described.class.new.load(path) }
let(:path) { 'path/that/should/exist' }
context 'when path' do
before do
allow(File).to receive(:exist?).with(path).and_return(true)
allow(File).to receive(:read).with(path).and_return('my content')
end
it { expect { subject }.to_not raise_error { Errno::ENOENT }
end
end
end
может быть, мне следует сделать что-то class_double
из File
Class. Я не уверен в том, как я предоставил, поэтому мне нужна некоторая информация о том, как это сделать обычным / передовым способом
Комментарии:
1. Проверьте FakeFS
Ответ №1:
Один из фундаментальных принципов разработки / дизайна, основанного на тестировании / поведении, заключается в том, чтобы не издеваться над тем, чем вы не владеете (придуман в книге Growing Object-Oriented Software, руководствуясь тестами Стива Фримена и Нэта Прайса).
Ваш пример нарушает этот принцип: вы не являетесь владельцем File
, поэтому вы не должны издеваться над ним.
Вместо этого вы могли бы создать свою собственную абстракцию для взаимодействия с файловой системой, которая обладает только той функциональностью, которая вам действительно требуется. Затем вы можете создать две реализации этой абстракции: ту, которая использует File
класс Ruby, и макет, который ничего не делает. Если вы хотите пофантазировать, вы даже можете создать тот, который имитирует файловую систему в памяти.
Конечно, теперь вы просто решили проблему: теперь у вас есть непроверенный код в вашей реализации файловой абстракции. Однако в идеале этот код должен быть «почти» тривиальным. И, очевидно, вы все равно можете провести интеграционный тест как для вашей реализации файловой абстракции, так и для интеграционного теста, в ConfigLoader
котором используется реальная реализация вместо макета или симуляции.
Вот некоторые дополнительные сведения, если вам интересно:
- Это не твое, Эрик Смит (8th Light)
- Не издевайтесь над тем, чем вы не владеете, Testdouble.com
- TDD: только те типы макетов, которые у вас есть, Марк Нидхэм (Neo4J)
- Не издевайтесь над тем, чем вы не владеете, Максим Иванов
- Не издевайтесь над тем, чем вы не владеете, кодовым хранилищем Мэтта
- Не издевайтесь над тем, чем вы не владеете: сценарий реального мира, Джованни Пинто
- Не издевайтесь над типами, которыми вы не владеете, Дэвид Чепак