Хобрук: Ваш путь к мастерству в программировании

Получение ошибок при выполнении теста в Rails для отношения объекта ActiveRecord

У меня есть частичное представление _patients.html.erb, где я хочу показать вложенный атрибут из модели консультации, поэтому я обращаюсь к объекту отношения ActiveRecord следующим образом:

мои модели

class Patient < ApplicationRecord
  belongs_to :medic
  has_many :consultations, dependent: :destroy
  accepts_nested_attributes_for :consultations
end

class Consultation < ApplicationRecord
  belongs_to :patient
end

на моем dashboard_controller.rb

..some code..

protected
    def reason_for_consultation(patient)
        patient = patient
        @reason = Consultation.where(patient_id: patient.id).order(created_at: :desc).limit(1)
        #=> @reason: #<ActiveRecord::Relation [#<Consultation id: 371, reason_for_consultation: "Sunt impedit adipisci molestiae doloremque sed.">]>
        @reason_for_consultation = @reason[0].reason_for_consultation
    end

    helper_method :reason_for_consultation

частичное представление _patients.html.erb

<% @patients.each do |patient| %>
    .. code ..
    <p>Reason for consultation: <%= reason_for_consultation(patient) %></p>
    .. code ..
<% end %>

Примечание: код работает нормально, показывает данные для каждого пациента в представлении, проблема в том, что когда я запускаю тесты (минитест), я получаю несколько предупреждений и ошибок, подобных этому:

  • DEPRECATION WARNING: #original_exception is deprecated. Use #cause instead. (more descriptions of the error followed by):
    • Capybara::ElementNotFound: Unable to find visible link, or
    • Ожидается, что ложь окажется правдой, или
    • Ожидаемый ответ будет ‹2XX: успех>, но был ‹500: Внутренняя ошибка сервера>

Но если я прокомментирую в своем частичном: <%# reason_for_consultation(patient) %> и снова запущу тесты, все будет пройдено.

Все ошибки связаны с взаимодействием с приборной панелью

Любая идея, что происходит и как это решить?

Редактировать:

Версии: - rails: 5.0.0.1 - minitest: 5.9.1 - ruby ​​2.3.3p222

тестовая трасса рельсов:

DEPRECATION WARNING: #original_exception is deprecated. Use #cause instead. (called from block in <class:DashboardFlowTest> at my_app/test/integration/dashboard_flow_test.rb:19)
DEPRECATION WARNING: #original_exception is deprecated. Use #cause instead. (called from block in <class:DashboardFlowTest> at my_app/test/integration/dashboard_flow_test.rb:19)
 FAIL["test_should_be_in_dashboard", DashboardFlowTest, 0.46483432999957586]
 test_should_be_in_dashboard#DashboardFlowTest (0.46s)
        Expected false to be truthy.
        test/integration/dashboard_flow_test.rb:20:in `block in <class:DashboardFlowTest>'

DEPRECATION WARNING: #original_exception is deprecated. Use #cause instead. (called from block in <class:DashboardFlowTest> at my_app/test/integration/dashboard_flow_test.rb:24)
DEPRECATION WARNING: #original_exception is deprecated. Use #cause instead. (called from block in <class:DashboardFlowTest> at my_app/test/integration/dashboard_flow_test.rb:24)
ERROR["test_should_be_show_new_patient_form", DashboardFlowTest, 0.5577200539992191]
 test_should_be_show_new_patient_form#DashboardFlowTest (0.56s)
Capybara::ElementNotFound:         Capybara::ElementNotFound: Unable to find visible link "Create Patient"
            test/integration/dashboard_flow_test.rb:25:in `block in <class:DashboardFlowTest>'

DEPRECATION WARNING: #original_exception is deprecated. Use #cause instead. (called from block in <class:DashboardFlowTest> at my_app/test/integration/dashboard_flow_test.rb:30)
DEPRECATION WARNING: #original_exception is deprecated. Use #cause instead. (called from block in <class:DashboardFlowTest> at my_app/test/integration/dashboard_flow_test.rb:30)
ERROR["test_should_be_show_patient_list_page", DashboardFlowTest, 0.6530102200049441]
 test_should_be_show_patient_list_page#DashboardFlowTest (0.65s)
Capybara::ElementNotFound:         Capybara::ElementNotFound: Unable to find visible link "Patient List"
            test/integration/dashboard_flow_test.rb:31:in `block in <class:DashboardFlowTest>'

DEPRECATION WARNING: #original_exception is deprecated. Use #cause instead. (called from block in <class:PaymentMethodsFlowTest> at my_app/test/integration/payment_methods_flow_test.rb:19)
DEPRECATION WARNING: #original_exception is deprecated. Use #cause instead. (called from block in <class:PaymentMethodsFlowTest> at my_app/test/integration/payment_methods_flow_test.rb:19)
ERROR["test_0001_log into dashboard as premium user", PaymentMethodsFlowTest, 4.802539983000315]
 test_0001_log into dashboard as premium user#PaymentMethodsFlowTest (4.80s)
Capybara::ElementNotFound:         Capybara::ElementNotFound: Unable to find visible link "Show Payment Methods"
            test/integration/payment_methods_flow_test.rb:21:in `block in <class:PaymentMethodsFlowTest>'

DEPRECATION WARNING: #original_exception is deprecated. Use #cause instead. (called from block (2 levels) in <class:ConsultNewPatientFlowTest> at my_app/test/integration/consult_new_patient_flow_test.rb:37)
DEPRECATION WARNING: #original_exception is deprecated. Use #cause instead. (called from block (2 levels) in <class:ConsultNewPatientFlowTest> at my_app/test/integration/consult_new_patient_flow_test.rb:37)
ERROR["test_0001_end to end consult a patient", #<Class:0x0055b32a91d1a0>, 4.885057498999231]
 test_0001_end to end consult a patient#Medic can consult a new patient Feature Test (4.89s)
Capybara::ElementNotFound:         Capybara::ElementNotFound: Unable to find visible link "Create Patient"
            test/integration/consult_new_patient_flow_test.rb:39:in `block (2 levels) in <class:ConsultNewPatientFlowTest>'

DEPRECATION WARNING: #original_exception is deprecated. Use #cause instead. (called from block (2 levels) in <class:PremiumLoginFlowTest> at my_app/test/integration/premium_login_flow_test.rb:20)
DEPRECATION WARNING: #original_exception is deprecated. Use #cause instead. (called from block (2 levels) in <class:PremiumLoginFlowTest> at my_app/test/integration/premium_login_flow_test.rb:20)
 FAIL["test_0001_login premium", #<Class:0x0055b32a8e22f8>, 5.003259566998167]
 test_0001_login premium#Medic with account and payment method Feature Test (5.00s)
        Expected false to be truthy.
        test/integration/premium_login_flow_test.rb:22:in `block (2 levels) in <class:PremiumLoginFlowTest>'

DEPRECATION WARNING: #original_exception is deprecated. Use #cause instead. (called from block in <class:DashboardControllerTest> at my_app/test/controllers/dashboard_controller_test.rb:21)
DEPRECATION WARNING: #original_exception is deprecated. Use #cause instead. (called from block in <class:DashboardControllerTest> at my_app/test/controllers/dashboard_controller_test.rb:21)
 FAIL["test_should_get_dashboard", DashboardControllerTest, 5.078975292002724]
 test_should_get_dashboard#DashboardControllerTest (5.08s)
        Expected response to be a <2XX: success>, but was a <500: Internal Server Error>
        test/controllers/dashboard_controller_test.rb:22:in `block in <class:DashboardControllerTest>'

  63/63: [==================================================================================================================] 100% Time: 00:00:05, Time: 00:00:05

Finished in 5.30410s
63 tests, 147 assertions, 3 failures, 4 errors, 0 skips

Редактировать 2:

Ожидаемый ответ будет ‹2XX: успех>, но был ‹500: Внутренняя ошибка сервера> my_app/test/controllers/dashboard_controller_test.rb:21

require 'test_helper'

class DashboardControllerTest < ActionDispatch::IntegrationTest
  # Needed for authenticate user
  include Warden::Test::Helpers

  setup do
    # Login medic for before_filter authenticate_user!
    @medic = medics(:medic_one)
    @medic.confirmed_at = Time.now
    @medic.save
    login_as(@medic, :scope => :medic)
    # Set payment for medic
    @medic.payment_methods.reload
  end

  test "should get dashboard" do
    get dashboard_index_url
    assert_response :success
  end
end

  • Можете ли вы включить трассировку стека? 19.07.2018
  • И отредактируйте свой пост и добавьте, какие версии Rails, Minitest и Ruby вы используете. 19.07.2018
  • конечно @JoshBrody 19.07.2018
  • Версии: - rails: 5.0.0.1 - minitest: 5.9.1 - ruby ​​2.3.3p222, @Phlip 19.07.2018
  • Почему в тестах работает Capybara? Простой функциональный тест может покрыть ваш код... 19.07.2018
  • @Phlip Капибара по какой-то причине вызывает эту ошибку? 19.07.2018
  • Отредактируйте свой пост и добавьте образец своих тестов. 19.07.2018
  • @Philip Я добавил образец теста, тебе нужен специальный тест? 19.07.2018

Ответы:


1

Сбой теста контроллера показывает, в чем ваша проблема, страница возвращает статус ошибки 500, а не статус 2XX, что говорит вам об ошибке при отображении страницы. Это также может быть причиной того, что Capybara не находит ни одного из ожидаемых элементов на странице (поскольку страница на самом деле не отображается). Если вы заглянете в свой test.log, он должен сказать вам, где именно в ваших шаблонах появляется ошибка, но, поскольку комментирование <%# reason_for_consultation(patient) % исправляет страницу, мы можем с уверенностью предположить, где ошибка.

Глядя на код для reason_for_consultation, мы видим, что если у пациента еще не было консультации, то @reason[0] будет nil, а @reason[0].reason_for_consultation вызовет ошибку при попытке позвонить reason_for_consultation на nil. Один из возможных способов исправить это — использовать оператор безопасной навигации и изменить строку на

@reason[0]&.reason_for_consultation

Примечание. В будущем вся реализация этой подпрограммы/частичной части, вероятно, должна быть реорганизована, чтобы удалить запрос N + 1, который у вас там происходит.

Что касается DEPRECATION WARNING строк о original_exception - невозможно сказать, откуда это на самом деле, без более глубокой трассировки стека, но попробуйте посмотреть на my_app/test/controllers/dashboard_controller_test.rb строку 21 и посмотреть, что там вызывается. Возможно, вам просто нужно обновить некоторые из ваших тестовых драгоценных камней.

19.07.2018
  • @reason[0]&.reason_for_consultation отлично работает, спасибо за объяснение, сейчас тесты проходят, буду следовать вашим рекомендациям по логу, и рефакторингу в будущем. большое тебе спасибо. 19.07.2018
  • Новые материалы

    Прогресс в технологии Трансформеров часть 3
    Многомасштабный управляющий сигнальный преобразователь для бесфазного синтеза движения (arXiv) Автор: Линтао Ван , Кун Ху , Лей Бай , Юй Дин , Ваньли Оуян , Чжиюн Ван . Аннотация:..

    Представляем поддержку компонентов Vue.js. Мгновенный HMR и многое другое.
    Хотя у FuseBox уже был плагин Vue, он был базовым и не имел многих функций, которые делали работу с Vue.js такой приятной. Однако с этим выпуском мы рады сообщить, что в FuseBox..

    Приключения в Javascript, часть 1
    Я продолжаю думать о том, чтобы писать больше, но чем больше я думаю об этом, тем меньше я это делаю. Итак, сегодня я перестал думать и начал писать. Отсюда можно только спускаться… В..

    Понимание дженериков в TypeScript: подробное руководство
    Введение TypeScript, строго типизированный надмножество JavaScript, хорошо известен своей способностью улучшать масштабируемость, удобочитаемость и ремонтопригодность приложений. Одной из..

    Учебные заметки JavaScript Object Oriented Labs
    Вот моя седьмая неделя обучения программированию. После ruby ​​и его фреймворка rails я начал изучать самый популярный язык интерфейса — javascript. В отличие от ruby, javascript — это более..

    Разбор строк запроса в vue.js
    Иногда вам нужно получить данные из строк запроса, в этой статье показано, как это сделать. В жизни каждого дизайнера/разработчика наступает момент, когда им необходимо беспрепятственно..

    Предсказание моей следующей любимой книги 📚 Благодаря данным Goodreads и машинному обучению 👨‍💻
    «Если вы не любите читать, значит, вы не нашли нужную книгу». - J.K. Роулинг Эта статья сильно отличается от тех, к которым вы, возможно, привыкли . Мне очень понравилось поработать над..