【问题标题】:Why adding association mark my model as not valid?为什么添加关联将我的模型标记为无效?
【发布时间】:2017-03-28 21:09:41
【问题描述】:

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

我已经为 Forecast 实现了一个模型。预测与其他模型(例如 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

我试图了解为什么会发生这种情况。任何人都知道为什么这些测试失败了?另外,有什么合适的方法来测试关联吗?

提前谢谢你。

【问题讨论】:

  • 如果你只使用belongs_to :forecast呢?
  • 要测试关联,您可以使用fixture。试试这个tutorial
  • @DiodonHystrix 如果我删除了 foreign_key: true,则测试正常。为什么会这样?删除foreign_key是否正确:true?并感谢关联测试教程:)
  • true 不是foreign_key 选项的有效值,foreign_key 是您指定外键列名称的地方,如果它不同于默认值(在这种情况下,默认值是forecast_id).
  • 有关belongs_to 选项的更多信息,请查看it。查看示例以更好地理解它:)

标签: ruby-on-rails ruby testing tdd minitest


【解决方案1】:
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

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

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

【讨论】:

  • 另一方面,我认为您可能真的错过了域建模的标记。将典型天气预报的字段拆分为多个表只会增加复杂性并导致性能问题。我认为您首先需要将其建模为每天的多个预测。每天没有一个预测有一堆不同的块。
  • 感谢您的建议。我对 Rails 比较陌生。是的,你是对的,我可以简化更多我的模型。我需要更多地考虑它们。
猜你喜欢
  • 2017-07-19
  • 2018-04-14
  • 1970-01-01
  • 2017-03-06
  • 1970-01-01
  • 2020-05-09
  • 2012-12-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多