为什么添加关联将我的模型标记为无效?

Why adding association mark my model as not valid?

我正在 Rails 开发一个简单的天气 API。 API 将给出给定日期的预报。预报会有风、温度、相对湿度等每小时的数据。

我已经为预测实施了一个模型。该预测与其他模型(例如 Wind)有关联 "has_many"。我为 Wind 对象开发了以下模型:

class Wind < ApplicationRecord
  belongs_to :forecast, foreign_key: true
  validates_presence_of :period
  validates :velocity, numericality: true, allow_blank: true
  validates :direction, length: { maximum: 2 }, allow_blank: true
end

在我尝试使用 TDD 时,我实施了以下测试(以及其他测试):

class WindTest < ActiveSupport::TestCase
  setup do
    @valid_wind = create_valid_wind
    @not_valid_wind = create_not_valid_wind
  end

  test 'valid_wind is valid' do
    assert @valid_wind.valid?
  end

  test 'valid_wind can be persisted' do
    assert @valid_wind.save
    assert @valid_wind.persisted?
  end

  test 'not_valid_wind is not valid' do
    assert_not @not_valid_wind.valid?
  end

  test 'not valid wind cannot be persisted' do
    assert_not @not_valid_wind.save
    assert_not @not_valid_wind.persisted?
  end

  test 'not_valid_wind has error messages for period' do
    assert_not @not_valid_wind.save
    assert_not @not_valid_wind.errors.messages[:period].empty?
  end

  test 'not_valid_wind has error messages for velocity' do
    assert_not @not_valid_wind.save
    assert_not @not_valid_wind.errors.messages[:velocity].empty?
  end

  test 'not_valid_wind has error messages for direction' do
    assert_not @not_valid_wind.save
    assert_not @not_valid_wind.errors.messages[:direction].empty?
  end

  private

  def create_valid_wind
    valid_wind = Wind.new
    valid_wind.direction = 'NO'
    valid_wind.velocity = 2
    valid_wind.period = '00-06'
    valid_wind.forecast_id = forecasts(:one).id
    valid_wind
  end

  def create_not_valid_wind
    not_valid_wind = Wind.new
    not_valid_wind.velocity = 'testNumber'
    not_valid_wind.direction = '123'
    not_valid_wind
  end
end

在我添加与预测的关联之前,这组测试已经通过:

belongs_to :forecast, foreign_key: true

确实,如果我删除该行,任何测试都会失败。但是对于模型中的那一行,以下测试失败了(它们是假的,测试期望是真的):

  test 'valid_wind is valid' do
    assert @valid_wind.valid?
  end

  test 'valid_wind can be persisted' do
    assert @valid_wind.save
    assert @valid_wind.persisted?
  end

我想了解为什么会这样。任何人都知道为什么这些测试失败了?另外,有什么正确的方法来测试关联吗?

提前致谢。

test 'valid_wind can be persisted' do
  assert @valid_wind.save
  assert @valid_wind.persisted?
end

此测试几乎毫无价值,因为您只是在测试测试设置是否正确,它不会告诉您有关被测应用程序的任何信息。

相反,在您的模型测试中,您应该在每次验证的基础上进行测试:

test 'does not allow non numerical values for velocity' do
  wind = Wind.new(velocity: 'foo')
  wind.valid?
  assert_match "is not a number", wind.errors.full_messages_for(:velocity)
end

test 'allows numerical values for velocity' do
  wind = Wind.new(velocity: 3)
  wind.valid?
  refute(wind.errors.include?(:velocity))
end

测试传递值通常只是有点用处,但如果出现错误,则可能很有价值。

在您的模型中,您真的不需要担心设置完全有效的记录 - 您的功能和集成测试无论如何都会涵盖这些内容。