参数错误测试状态机
ArgumentError testing State Machine
我正在使用以下版本:
ruby 2.5.5
rails 5.2.3
state_machines-activerecord 0.6.0
我有一个模型 Foo,上面有一个状态机:
class Foo < ApplicationRecord
def post_activate
puts "hello from sunny post_activate"
end
state_machine :state, initial: :initial do
state :active
after_transition any => :active, :do => :post_activate
event :activate do
transition initial: :active
end
end
end
我正在尝试编写一个 rspec 测试以确保 post_activate
在转换到状态 :active 后被调用。
我可以从 Rails 控制台测试正常:
2.5.5 :001 > thinger = Foo.new
=> #<Foo id: nil, state: "initial", created_at: nil, updated_at: nil>
2.5.5 :002 > thinger.activate
(0.1ms) begin transaction
Foo Create (0.4ms) INSERT INTO "foos" ("state", "created_at", "updated_at") VALUES (?, ?, ?) [["state", "active"], ["created_at", "2019-06-28 21:35:22.555917"], ["updated_at", "2019-06-28 21:35:22.555917"]]
hello from sunny post_activate
(0.7ms) commit transaction
=> true
然而,当我 运行 我的测试时:
describe 'Foo' do
it 'should fire post_activate' do
foo = Foo.new
expect(foo).to receive(:post_activate)
foo.activate
end
end
我收到以下错误:
1) Foo should fire post_activate
Failure/Error: foo.activate
ArgumentError:
Wrong number of arguments. Expected 0, got 1.
有趣的是,另一个测试 运行 正确无误:
it 'should change the state' do
foo = Foo.new
expect{
foo.activate
}.to change {
foo.state
}.from('initial').to('active')
end
此测试通过并打印我的调试消息。
我尝试将参数放入 post_activate
定义中:
def post_activate(arg)
puts arg
puts "hello from sunny post_activate"
end
现在测试通过了 - puts 语句显示传入的对象是 StateMachines::Transition
#<StateMachines::Transition:0x00007fd5d3534228>
hello from sunny post_activate
我不确定这是如何工作的 - 我知道如何使参数可选,但我不知道如何选择性地传递参数。
无论如何 - 如果我将参数添加到我的方法定义中,测试就会通过。但我不想添加一个我不使用的参数,只是为了让我的规格通过。我该如何解决?
RSpec 正在验证 validate_arguments!
中的代理,正在调用 post_activate
当前转换。如果您将 byebug
之类的内容添加到您的 Gemfile 中,并且有条件地将相同的 byebug 添加到 Rspec 的 validate_arguments!
中,您可以看到它:
@method_reference.with_signature do |signature|
verifier = Support::StrictSignatureVerifier.new(signature, actual_args)
byebug unless verifier.valid?
raise ArgumentError, verifier.error_message unless verifier.valid?
这将使您能够访问 actual_args:
(byebug) actual_args
[#<StateMachines::Transition ...]
因此,要解决您的问题,您只需将省略的参数添加到您的回调中(正如您清楚地已经弄清楚的那样):
def post_activate(_)
要确定下划线为何这样使用,请查看 Ruby Style Guide。
我正在使用以下版本:
ruby 2.5.5
rails 5.2.3
state_machines-activerecord 0.6.0
我有一个模型 Foo,上面有一个状态机:
class Foo < ApplicationRecord
def post_activate
puts "hello from sunny post_activate"
end
state_machine :state, initial: :initial do
state :active
after_transition any => :active, :do => :post_activate
event :activate do
transition initial: :active
end
end
end
我正在尝试编写一个 rspec 测试以确保 post_activate
在转换到状态 :active 后被调用。
我可以从 Rails 控制台测试正常:
2.5.5 :001 > thinger = Foo.new
=> #<Foo id: nil, state: "initial", created_at: nil, updated_at: nil>
2.5.5 :002 > thinger.activate
(0.1ms) begin transaction
Foo Create (0.4ms) INSERT INTO "foos" ("state", "created_at", "updated_at") VALUES (?, ?, ?) [["state", "active"], ["created_at", "2019-06-28 21:35:22.555917"], ["updated_at", "2019-06-28 21:35:22.555917"]]
hello from sunny post_activate
(0.7ms) commit transaction
=> true
然而,当我 运行 我的测试时:
describe 'Foo' do
it 'should fire post_activate' do
foo = Foo.new
expect(foo).to receive(:post_activate)
foo.activate
end
end
我收到以下错误:
1) Foo should fire post_activate
Failure/Error: foo.activate
ArgumentError:
Wrong number of arguments. Expected 0, got 1.
有趣的是,另一个测试 运行 正确无误:
it 'should change the state' do
foo = Foo.new
expect{
foo.activate
}.to change {
foo.state
}.from('initial').to('active')
end
此测试通过并打印我的调试消息。
我尝试将参数放入 post_activate
定义中:
def post_activate(arg)
puts arg
puts "hello from sunny post_activate"
end
现在测试通过了 - puts 语句显示传入的对象是 StateMachines::Transition
#<StateMachines::Transition:0x00007fd5d3534228>
hello from sunny post_activate
我不确定这是如何工作的 - 我知道如何使参数可选,但我不知道如何选择性地传递参数。
无论如何 - 如果我将参数添加到我的方法定义中,测试就会通过。但我不想添加一个我不使用的参数,只是为了让我的规格通过。我该如何解决?
RSpec 正在验证 validate_arguments!
中的代理,正在调用 post_activate
当前转换。如果您将 byebug
之类的内容添加到您的 Gemfile 中,并且有条件地将相同的 byebug 添加到 Rspec 的 validate_arguments!
中,您可以看到它:
@method_reference.with_signature do |signature|
verifier = Support::StrictSignatureVerifier.new(signature, actual_args)
byebug unless verifier.valid?
raise ArgumentError, verifier.error_message unless verifier.valid?
这将使您能够访问 actual_args:
(byebug) actual_args
[#<StateMachines::Transition ...]
因此,要解决您的问题,您只需将省略的参数添加到您的回调中(正如您清楚地已经弄清楚的那样):
def post_activate(_)
要确定下划线为何这样使用,请查看 Ruby Style Guide。