Имитация отсутствующего драгоценного камня в юнит-тестах Ruby - PullRequest
1 голос
/ 23 апреля 2010

Есть ли способ имитировать отсутствие драгоценного камня для определенных юнит-тестов, кроме фактического удаления и последующей переустановки драгоценного камня во время тестирования?

Я пишу утилиту командной строки и хочу убедиться, что мои тесты охватывают случаи, когда у пользователя может не быть всех гемов, которые я поддерживаю. Например, я использую fsevents - специфичный для Leopard пакет для мониторинга событий файловой системы - который никогда не будет присутствовать в других системах, а также рычание, являющееся чисто необязательным.

Ответы [ 4 ]

2 голосов
/ 23 апреля 2010

Я использовал метод, который я написал под названием with_constant_unavailable. Я забыл точные детали, но я думаю, что это было что-то вроде этого:

def with_constant_unavailable(constant_name, &block)
  match_data = constant_name.to_s.match(/(?:(.+)::)?(.+)/)
  if match_data[2]
    owning_module, constant_name = match_data[1].constantize, match_data[2]
  else
    owning_module, constant_name = Object, constant_name.to_s
  end
  original_constant = owning_module.send :remove_const, constant_name
  begin
    yield
  ensure
    owning_module.const_set constant_name, original_constant
  end
end

Затем вы можете запустить тест следующим образом:

def test_uses_foo_when_bar_unavailable
  with_constant_unavailable(Bar) do
    assert baz.quux == Foo
  end
end
1 голос
/ 23 апреля 2010

Я бы попытался сбросить путь к драгоценному камню, что-то вроде:

require 'rubygems' 
Gem.clear_paths 
ENV['GEM_HOME'] = "" 
ENV['GEM_PATH'] = "" 

Я бы тоже его сохранил и потом восстановил.

1 голос
/ 23 апреля 2010

Вы можете проверить существование константы.

if !defined?(Growl)
  ...
end

В ваших тестах вы можете временно переименовать / отключить / удалить константу для имитации отсутствующей библиотеки.

0 голосов
/ 23 апреля 2010

Как только вы что-то require сделаете, я думаю, что это довольно сложно отменить. Однако вы могли бы иметь отдельный набор тестов, которые всегда выполняются в отдельном экземпляре интерпретатора Ruby, и вызывать их как другую задачу rake. Так что у вас может быть что-то вроде этого:

Rake::TestTask.new(:no_growl_test) do |t|
  t.libs << 'lib'
  t.pattern = 'test/compatibility/no_growl.rb'
end

Идея в том, что это будет работать в новой, "чистой" среде, в которой вы никогда не сможете загрузить Growl. Некоторые из других пользователей предложили способы заставить Rubygems не находить данный драгоценный камень, и это может быть даже возможно в Gem API.

В качестве альтернативы, используя JRuby, не так уж сложно создать несколько непересекающихся сред выполнения, но это, вероятно, излишне для вашей работы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...