Блок тестирования с skip_before_action не сбрасывается после использования TDD - PullRequest
0 голосов
/ 07 июня 2018

Я использую Rails 5.2 и провожу некоторое тестирование.Я пытаюсь выполнить свое модульное тестирование с помощью ActionController::TestCase и обнаружил, что @controller.class.skip_before_action :verify_user не перезагружает контроллер автоматически перед переходом к следующему методу тестового модуля.

Теперь, когда тесты рельсов рандомизируются при каждом запуске, определенный модуль дает сбойиногда, а не в другие времена.Я подумал, что ожидал HTTP 401, но получил 200. Потому что контроллер проигнорировал before_action :verify_user.

Я мог бы установить @controller.class.before_action :verify_user в конце каждой единицы (и это работает!), Но это не должно бытьпредставитель тестирования sys для сброса контекста перед каждым запуском?

Дайте отрывок моего кода:

class ApiSiteMetricsTest < ActionController::TestCase
  tests Api::SiteMetricsController

  def test_1_index
    @controller.class.skip_before_action :verify_user,raise: false

    get "index",  params:{ 
        "format"=>"json",
        "site_metric_value"=>{
            "site_metric_id"=>2403, 
            "date_acquired"=>"2018-03-14T01:44:00+05:30", 
            "site_id"=>3840, 
            "lab_device_details"=>"", 
            "comment"=>"", 
            "sender_affiliation"=>"", 
            "float_value"=>""
        }
    }
    assert_response :success
    File.open("#{Rails.root}/del.html", "wb") { |f| f.write(@response.body) }        
    #Do I have to do this o every test?
    #@controller.class.before_action :verify_user
  end
  ...

1 Ответ

0 голосов
/ 07 июня 2018

Вы абсолютно правы, что каждый тест должен сбрасывать состояние системы после запуска.Тесты должны быть полностью независимыми - именно поэтому они выполняются в случайном порядке (по умолчанию).

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

Например, что если ваш тест изменит переменную ENV?Или звонит Timecop.freeze?Или добавляет запись базы данных через второе соединение с базой данных ?Или устанавливает глобальную переменную?...

Иногда вам нужно сбросить состояние вручную!

В этом случае я бы сделал следующее:

class ApiSiteMetricsTest < ActionController::TestCase
  tests Api::SiteMetricsController

  def test_1_index
    @controller.class.skip_before_action :verify_user,raise: false

    # ...

    ensure

    @controller.class.before_action :verify_user
  end
end

ensure есть, чтобыдаже если этот тест не пройден, состояние должно быть сброшено независимо от того, что не влияет на другие тесты или нет.

В некоторых случаях может оказаться удобным использовать MiniTest 's setup и teardown методы для обеспечения этой функциональности.(Эквивалентно before и after крючкам в rspec).

...