Есть ли лучший способ проверить, что сценарий вызывается в контроллере, отличном от ожидаемого_y_instance_of (# {ControllerClass}). Для получения? - PullRequest
0 голосов
/ 24 января 2020

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

В настоящее время я использую

expect_any_instance_of(ConfigurationsController)
  .to receive(:system)
  .with('sh bin/resque/kill_resque_workers')
  .and_return(true)

в функции spe c и это работает, но rubocop жалуется на использование Ожидаем__данных_инстанций_, и мне сказали использовать этот метод, только если не было лучшего способа.

Есть ли лучший способ проверить это? Например, есть ли способ получить экземпляр используемого контроллера или лучший тест для этого?

1 Ответ

1 голос
/ 24 января 2020

Лучшим вариантом было бы не встроить системный вызов в ваш контроллер. Вместо этого создайте отдельный объект, который знает, как убить ваши рабочие процессы и вызывать его с вашего контроллера. Для этого часто используется шаблон объекта службы . Это значительно облегчает заглушение / шпион / макет зависимости и гарантирует, что она останавливается на уровне приложения dry.

Это также позволяет вам тестировать объект изолированно. Тестирование старых ruby объектов действительно просто. Тестирование контроллеров не выполняется.

module WorkerHandler
  def self.kill_all
    system 'sh bin/resque/kill_resque_workers'
  end
end

# in your test
expect(WorkerHandler).to receive(:kill_all)

Если ваш метод сервисного объекта выполняется на экземплярах класса, вы можете использовать stub_const , чтобы заглушить новый метод, чтобы он возвращал издевательства / шпионы.

Еще одно более новое решение - внедрение зависимостей через промежуточное ПО Rack. Вы просто пишете часть промежуточного программного обеспечения , которое внедряет ваш объект в env . env - это переменная состояния, которая прошла весь путь промежуточного стека до вашего приложения. Вот как работает Warden, например. Вы можете передать env вместе со своим spe c, когда вы делаете http-вызовы на вашем контроллере или используете before { session.env('foo.bar', baz) }.

...