2017-01-04 2 views
2

У меня есть приложение 4.1.16 API, которое проверено с помощью RSpec 3.4.0, и я испытываю проблемы с классами тестирования с одинаковым именем в другом модуль.Rails и RSpec: Контроллеры тестирования с тем же именем в разных пространствах имен (модуль)

Структура:

app/controllers/bar/notifications_controller.rb 

class Bar::NotificationsController < ApiController 
    ... 
end 

и контроллер с тем же именем в другом модуле:

app/controllers/foo/bar/notifications_controller.rb 

module Foo 
    class Bar::NotificationsController < ApiController 
    ... 
    end 
end 

Foo новый модуль и не имеет испытаний еще. После его добавления все соответствующие тесты контроллера для старого Bar::NotificationsController начали сбой.

Спецификация Файл:

spec/controllers/bar/notifications_controller_spec.rb 

require 'spec_helper' 

describe Bar::NotificationsController, type: :controller do 
    ... 
end 

Все тесты в этом файле спецификации не в состоянии с той же ошибкой:

RuntimeError: 
    @controller is nil: make sure you set it in your test's setup method. 

Проблема не существует, когда я изменить имя контроллера в Foo модуле :

app/controllers/foo/bar/foo_notifications_controller.rb 

module Foo 
    class Bar::FooNotificationsController < ApiController 
    ... 
    end 
end 

Я уже пробовал добавление сверху файла спецификации require 'bar/notifications_controller' и с использованием имени класса в виде строки describe "Bar::NotificationsController, type: :controller, но это не решило проблему (та же ошибка).

Почему это происходит? Каково решение?

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

Большое спасибо за вашу помощь!

+0

Можете ли вы попытаться определить пространства имен с помощью 'module Bar' вместо определения в самом имени класса? – emaillenin

+1

Попробуйте 'описать :: Bar :: NotificationsController, type:: controller do' –

+0

К сожалению, это не сработало. – Anita

ответ

1

В целом, я принимаю к включению все namespacing в определении класса. Что-то вроде:

app/controllers/foo/bar/notifications_controller.rb 

class Foo::Bar::NotificationsController < ApiController 
    ... 
end 

While, на первый взгляд, это может выглядеть так же, как:

app/controllers/foo/bar/notifications_controller.rb 

module Foo 
    class Bar::NotificationsController < ApiController 
    ... 
    end 
end 

Это, по сути, разные. Разница заключается в том, как Rails обрабатывает автозагрузку констант. Я не буду вдаваться в подробности здесь, потому что это более длинная тема, и в веб-сфере есть хорошие статьи/сообщения.

Вы можете найти хорошие статьи о том, как Rails обрабатывает автозагрузку как this one (или попробовать погуглить rails constant loading)

Кроме того, как отмечается в статье, Ruby постоянная нагрузка действует иначе, чем Rails загрузки. Хорошую информацию о постоянной загрузке Ruby можно найти here (или попробуйте Googling ruby constant loading).

+0

Спасибо, это сработало! Не могли бы вы вкратце объяснить, почему это происходит?Или какой-то ресурс по теме? Я бы ожидал, что модули и классы, написанные в обоих направлениях, будут вести себя так же, как они - одно и то же: | – Anita

Смежные вопросы