Как мне проверить, что запись была создана в Rails? - PullRequest
0 голосов
/ 03 декабря 2018

У меня есть небольшое приложение на Rails с базой данных, которая содержит Languages.Каждый из этих Languages может быть изменен, и я хочу отслеживать их изменения.
Я делаю это, создавая запись Audit при изменении объекта.Это Audit имеет поле has_many :languages, through: :audit_language_couplings, которое проверяет связь.

class Audit < ApplicationRecord
  belongs_to :audit_type

  has_many :audit_language_couplings
  has_many :languages, through: :audit_language_couplings

  validates_presence_of :audit_type, :admin_id, :date, :before
end

class Language < ApplicationRecord
  has_many :audit_language_couplings
  has_many :audits, through: :audit_language_couplings

  validates_presence_of :iso_code, :display_name, :keyboard_layout, :flag_url, :luis_app_identification, :luis_authorized_key, :luis_location
end

Аудит создается путем вызова метода create_audit() в LanguagesController при вызове метода PUT, DELETE или POST.У меня также есть конечные точки /languages/:id/audits, которые возвращают все проверки для данного языка в JSON.

Метод create_token():

def create_audit(type, admin_id)
    @language.audits.create(
      audit_type_id: type,
      admin_id: admin_id,
      date: Time.now.to_date,
      before: @language.to_s # TODO: Use the to-be-created to_json() or to_s() method instead.
    )
  end

Это также природа моей проблемы (я думаю).В настоящее время я тестирую мой API с запросами RSpec и Factory.Когда я создаю или обновляю Language в тестах, по какой-то причине не создается Audits.Но я знаю, что код работает, потому что он работает, когда я делаю это вручную с почтальоном в моей среде разработки.

FactoryBot.define do
  factory :language do
    iso_code { Faker::Address.country_code }
    display_name { Faker::Address.country }
    keyboard_layout { Faker::Internet.url }
    flag_url { Faker::Internet.url }
    luis_app_identification { Faker::Lorem.characters(5) }
    luis_authorized_key { Faker::Lorem.characters(5) }
    luis_location { Faker::Lorem.characters(5) }
  end
end

В настоящее время я структурировал свои тесты так:

describe 'POST /admin/language' do
    let(:valid_attributes) do
      {
        payload: {
          iso_code: 'en-US',
          display_name: 'English (US)',
          keyboard_layout: 'QWERTY',
          flag_url: '/public/images/en-US.png',
          luis_app_identification: 'test',
          luis_authorized_key: 'test',
          luis_location: 'test'
        }
      }
    end

    context 'when the request is valid' do
      before { post '/admin/languages', params: valid_attributes, headers: token_header }

      it 'creates a language' do
        expect(json['iso_code']).to eq('en-US')
      end

      it 'returns status code 201' do
        expect(response).to have_http_status(201)
      end

      context 'an audit should be made for the change' do
        before { get "/admin/languages/#{language_id}/audits", headers: token_header }

        it 'creates 1 audit' do
          expect(json.size).to eq 1
        end

        it 'is an audit of type 1 [ADD]' do
          expect(json[0]['audit_type_id']).to eq 1
        end
      end
    end

    context 'when the request is invalid' do
      before do
        post '/admin/languages', headers: token_header, params:
          {
            payload: {
              display_name: 'English (US)',
              keyboard_layout: 'QWERTY',
              flag_url: '/public/images/en-US.png',
              luis_app_identification: 'test',
              luis_authorized_key: 'test',
              luis_location: 'test'
            }
          }
      end

      it 'returns status code 422' do
        expect(response).to have_http_status(422)
      end

      it 'returns a validation failure message' do
        expect(response.body).to match(/Validation failed: Iso code can't be blank/)
      end
    end
  end

Проверка, где я проверяю, что проверки не пройдены, потому что при выполнении кода с RSpec возвращается 0 проверок.

Я думаю, что я делаю что-то не так с фабриками, но я не уверен, пожалуйста, дайте мне знать!

Ура

Ответы [ 3 ]

0 голосов
/ 03 декабря 2018

Вам нужно проверить, что когда происходит сообщение, количество Audit экземпляров увеличивается на один.Я бы сделал это так:

subject { post '/admin/languages', params: valid_attributes, headers: token_header }
it 'creates an audit'
  expect { subject }.to change { Audit.count }.by(1)
end

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

0 голосов
/ 03 декабря 2018

Ответы как Pennycracker, так и ReggieB были правильными или фактически частью общей картины.

Часть о create!() Шебанге привела меня к актуальной проблеме.Фабрики не создали AuditType, от которого зависел Audit.
ReggieB предположил, что моя тестовая установка была ошибочной, потому что я тестировал вложенный запрос.

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

context 'when the request is valid' do
  before { post '/admin/languages', params: valid_attributes, headers: token_header(admin_id: admin.id) }

  it 'returns status code 201' do
    expect(response).to have_http_status(201)
  end

  context 'the audit system has to be updated' do
    it 'creates 1 audit' do
      expect(Audit.all.size).to eq(1)
    end

    it 'should have type 1 [ADD]' do
      expect(Audit.first.audit_type.id).to eq(1)
    end
  end
end

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

Спасибо всем за помощь.

0 голосов
/ 03 декабря 2018

Трудно точно сказать, что происходит на основе предоставленного кода, но одну вещь, которую вы можете попробовать, это изменить ваш create_audit метод на:

def create_audit(type, admin_id)
    @language.audits.create!(

Добавление ! (удар) кcreate метод вызовет исключение, если по какой-то причине создание завершится неудачно, что должно появиться в ваших журналах RSpec.Это должно по крайней мере помочь вам найти источник проблемы.

...