Rails и MiniTest: Как написать тесты для чего-либо в app / lib / mymodule (класс не найден)? - PullRequest
0 голосов
/ 16 мая 2019

Rails 5.2 здесь. Я хочу проверить класс, определенный в app/lib/legacy/export.rb:

# app/lib/legacy/export.rb
module Legacy
  class Export
    def initialize ; end
  end
end

Тем не менее, тест в test/services/legacy_export_test.rb

# test/services/legacy_export_test.rb
require 'test_helper'

class LegacyExportTest < ActiveSupport::TestCase
  test 'can be initialized' do
    Legacy::Export.new
  end
end

выплюнет NameError: uninitialized constant Legacy::Export.

Это хорошо работает, если я добавлю определение класса в app/lib/export.rb (и уберу определение module). Я также могу ссылаться на этот класс в контроллерах и в консоли rails (rails c).

Попытка обратиться к классу, начинающемуся с верхнего уровня - "пространство имен" (::Legacy::Export), также не помогает. Я нахожу ответы на вопросы, как ссылаться на папки lib (и подкаталоги) в папке test/, но это не то, что мне нужно.

require 'lib/legacy/export скажет мне cannot load such file, как и require 'legacy/export'.

Я предположил, что (Auto) Load-вещи Rails и MiniTest одинаковы, но очевидно, что есть некоторая дополнительная конфигурация, которую нужно сделать.

Что должно быть сделано? Где я могу найти эту информацию?

1 Ответ

1 голос
/ 17 мая 2019

Проблема в том, что ваше пространство имен / путь к классу не соответствует тому, как автозагрузка Rails работает из коробки.

Когда вы используете класс, который ранее не был объявлен,Rails по умолчанию будет искать определенные пути (определенные для config.autoload_paths)

  • app / controllers
  • app / controllers / Concers
  • app / models
  • приложение / модели / проблемы
  • ...

Когда вы используете User в первый раз, так как он еще не определен (пока), он будет проходить по этим путями попробуйте запросить app / controllers / user.rb, app / controllers / Concers / user.rb, app / models / user.rb, пока он не найдет User class

, если ваш класс находится в пространстве имен какLegacy :: Export, затем он будет искать app / models / legacy / export.rb, app / models / беспокойства / legacy / export.rb, app / controllers / legacy / export.rb и т. Д.

Вот почему он не может найти ваш класс: ваш файл находится на app/lib, это не входит в пути, которые Rails использует для поиска.

Есть разныерешения:

Опция # 1

Требуется файл явно.(Рубиновый путь)

require_relative '../../app/lib/legacy/export'

Опция # 2

Добавить app/lib к autoload_pathconfig/application.rb) (Rails Way)

module YourApp
  class Application < Rails::Application
    # ...
    config.autoload_paths << Rails.root.join("app/lib")
  end
end

Параметр # 3

Адаптировать пространство имен для соответствия ожидаемым автозагрузке (вместо изменения конфигурации)

Пример: переместить файл в нечто вроде app/models/legacy/export.rb

...