如何验证已在Rails中创建记录?

时间:2018-12-03 16:17:02

标签: ruby-on-rails ruby validation rails-activerecord

我有一个小的Rails应用程序,其数据库包含不同的OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); 。每个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端点,该端点返回JSON中给定语言的所有审核。

/languages/:id/audits方法:

create_token()

这也是我问题的本质(我认为)。 我目前正在使用RSpec和Factory机器人请求测试我的API。当我在测试中创建或更新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 时,由于某种原因没有创建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

我检查审计的测试失败,因为使用RSpec运行代码时返回了0个审计。

我认为我的工厂做错了,但我不确定,请告诉我!

欢呼

3 个答案:

答案 0 :(得分:1)

基于所提供的代码,很难确切说明发生了什么,但是您可以尝试的一件事是将create_audit方法更改为:

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

如果由于某种原因创建失败,则将!(爆炸)添加到create方法将引发异常,该异常应显示在RSpec日志中。至少应该可以帮助您找到问题的根源。

答案 1 :(得分:1)

您需要检查的是,发布帖子时,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终结点之后调用另一个API)来测试一次审计(不检查规范之前的审计次数)。

答案 2 :(得分:0)

Pennycracker和ReggieB的答案都是正确的,或者实际上是大局的一部分。

关于create!() shebang的部分使我想到了实际的问题。工厂没有创建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

每个示例之后,数据库清洁器gem都会清洁数据库,因此检查第一个Audit的工作原理与预期的更改相同。

感谢大家的帮助。