问答。 Trailbalzer 测试 - 契约法的含义
Q&A. Trailbalzer Testing - Implications of contract method
以下问答基于 Trailblazer book pp. ~50-60 中给出的示例,并根据我的特定要求进行了改编。您可以简单地将 ARInvoice
和 ar_invoice
视为 Thing
和 thing
,以了解书中的一般情况。
我的 operation.rb
文件是:
class ARInvoice < GLTransaction class Create <
Trailblazer::Operation
include( Model )
model( ARInvoice, :create )
contract() do
property( :invoice_number )
property( :currency_code )
property( :forex_rate )
property( :gl_account_id )
validates( :invoice_number, :presence => true )
validates( :currency_code, :presence => true )
end
def process( params )
@model = ARInvoice.new # have to use instance variable here
validate( params[ :ar_invoice ], @model ) do |f|
f.save
end
end
end
end
我从开拓者书中改编了这个测试:
it("INSERTs a valid invoice") do
test_time = Time.now
puts(test_time)
ar_invoice = ARInvoice::Create.(
:ar_invoice => {
:invoice_number => 101,
:gl_account_id => 1,
:effective_from => test_time.to_s
}
).model
ar_invoice.persisted?.must_equal(true)
ar_invoice.invoice_number.must_equal(101)
ar_invoice.transaction_type.must_equal('IN')
ar_invoice.effective_from.must_equal(test_time)
ar_invoice.superseded_after.must_equal(nil)
end
我得到了这个错误:
ar_invoice crud Create#test_0001_INSERTs a valid invoice: \
ActiveRecord::StatementInvalid: SQLite3::ConstraintException: \
gl_transactions.effective_from may not be NULL: \
INSERT INTO "gl_transactions" . . .
但我也看到了这个:
# Running:
2016-02-08 11:24:35 -0500
E
因此,test_time 值已设置。为什么它没有进入 effective_from
属性?
我在下面给出的答案。
问题是我没领会Trailblazer (TBR)中contract
do/end
块的意义。我最初读这本书的方式是合同与形式有关。我在 RoR 方面的经验使我将 form 一词映射到 view 一词。我的错。但也可能绊倒其他人。
正确的合同块包含缺少的属性:effective_from
contract() do
property( :invoice_number )
property( :currency_code )
property( :forex_rate )
property( :gl_account_id )
property( :effective_from )
validates( :invoice_number, :presence => true )
validates( :currency_code, :presence => true )
end
现在,如果我将单词 form
映射到 params[ :model ]
,它会帮助我。因为调用 process
方法时在 params[ :model ]
哈希中查找的属性仅限于 contract
do/end
块中明确列出的那些属性; 这就是为什么使用 TBR 时不需要强参数的原因。
请注意,原始测试仍然失败,因为未满足 currency_code
验证。但在编写此测试时这是故意的。
以下问答基于 Trailblazer book pp. ~50-60 中给出的示例,并根据我的特定要求进行了改编。您可以简单地将 ARInvoice
和 ar_invoice
视为 Thing
和 thing
,以了解书中的一般情况。
我的 operation.rb
文件是:
class ARInvoice < GLTransaction class Create <
Trailblazer::Operation
include( Model )
model( ARInvoice, :create )
contract() do
property( :invoice_number )
property( :currency_code )
property( :forex_rate )
property( :gl_account_id )
validates( :invoice_number, :presence => true )
validates( :currency_code, :presence => true )
end
def process( params )
@model = ARInvoice.new # have to use instance variable here
validate( params[ :ar_invoice ], @model ) do |f|
f.save
end
end
end
end
我从开拓者书中改编了这个测试:
it("INSERTs a valid invoice") do
test_time = Time.now
puts(test_time)
ar_invoice = ARInvoice::Create.(
:ar_invoice => {
:invoice_number => 101,
:gl_account_id => 1,
:effective_from => test_time.to_s
}
).model
ar_invoice.persisted?.must_equal(true)
ar_invoice.invoice_number.must_equal(101)
ar_invoice.transaction_type.must_equal('IN')
ar_invoice.effective_from.must_equal(test_time)
ar_invoice.superseded_after.must_equal(nil)
end
我得到了这个错误:
ar_invoice crud Create#test_0001_INSERTs a valid invoice: \
ActiveRecord::StatementInvalid: SQLite3::ConstraintException: \
gl_transactions.effective_from may not be NULL: \
INSERT INTO "gl_transactions" . . .
但我也看到了这个:
# Running:
2016-02-08 11:24:35 -0500
E
因此,test_time 值已设置。为什么它没有进入 effective_from
属性?
我在下面给出的答案。
问题是我没领会Trailblazer (TBR)中contract
do/end
块的意义。我最初读这本书的方式是合同与形式有关。我在 RoR 方面的经验使我将 form 一词映射到 view 一词。我的错。但也可能绊倒其他人。
正确的合同块包含缺少的属性:effective_from
contract() do
property( :invoice_number )
property( :currency_code )
property( :forex_rate )
property( :gl_account_id )
property( :effective_from )
validates( :invoice_number, :presence => true )
validates( :currency_code, :presence => true )
end
现在,如果我将单词 form
映射到 params[ :model ]
,它会帮助我。因为调用 process
方法时在 params[ :model ]
哈希中查找的属性仅限于 contract
do/end
块中明确列出的那些属性; 这就是为什么使用 TBR 时不需要强参数的原因。
请注意,原始测试仍然失败,因为未满足 currency_code
验证。但在编写此测试时这是故意的。