我正在学习TDD和rails。我正在伤害自己的“逻辑”问题。让我先介绍一下情况。
我们有3个模型:Project
,Mission
,Attachment
。我像这样创建了它们
rails g model Mission
rails g model Project
rails g model Attachment title:string attachable:references{polymorphic}
rake db:migrate
生成此schema.rb
ActiveRecord::Schema.define(version: 20180307200338) do
create_table "attachments", force: :cascade do |t|
t.string "attachable_type"
t.integer "attachable_id"
t.string "title"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["attachable_type", "attachable_id"], name: "index_attachments_on_attachable_type_and_attachable_id"
end
create_table "missions", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "projects", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
对于模型,我们有:
# app/models/mission.rb
class Mission < ApplicationRecord
has_many :attachments, :as => :attachable
end
# app/models/project.rb
class Project < ApplicationRecord
has_many :attachments, :as => :attachable
end
# app/models/attachment.rb
class Attachment < ApplicationRecord
belongs_to :attachable, polymorphic: true
end
现在我们有了上下文,我想介绍一下我的“逻辑”问题。对我来说,创建像这样的Attachment
是完全合乎逻辑的:
Mission.find(1).attachments.create(file: 'my-file.jpg')
Project.find(1).attachments.create(file: 'my-file.jpg')
但很难想象自己会创建这样的附件:
Attachment.create(attachable: Mission.find(1))
Attachment.create(attachable: Project.find(1))
在开始TDD之前,我从没想过这个。我总是使用第一种方法就是这样。但现在我正在为我的附件模型编写测试,最后我做了类似的事情:
require 'test_helper'
class AttachmentTest < ActiveSupport::TestCase
test "should be valid" do
resource = build(:attachment)
assert resource.valid?
end
# FIXME is 'attachable' the final name?
test "should require attachable" do
resource = build(:attachment, attachable: nil)
assert resource.invalid?
end
test "should require file" do
resource = build(:attachment, file: nil)
assert resource.invalid?
end
end
不知何故,我正在测试永远不会发生的情景build(:attachment)
。
所以我的问题是:我是否应该辞职以“我必须这样做以证明Project.attachments.build()
会起作用”?
我也可以在Project
和Mission
中测试,例如:
这变得令人困惑。
在测试方面,如何测试这种关系?
很抱歉长篇(可能)有点令人困惑的帖子。
修改
问题奖金有一种方法可以简单地说“我们不能从附件中创建并且必须通过关系”
答案 0 :(得分:1)
在我看来,您正在尝试测试内置rails中的功能:
has_many :attachments
accepts_nested_attributes_for :attachments
autosave
的{{1}} has_many
另外,你自己说过:
不知何故,我测试了永远不会发生的情景
has_many :attachments
。
为什么要这么麻烦?
您希望测试对象以确保它们响应规范。例如,如果您想确保build(:attachment)
必须 Attachment
,那么您可以写:
attachable
这就是我认为,这是确保您对属性进行状态验证的最佳选择。