ArgumentError测试状态机

问题描述 投票:1回答:1

我正在使用以下版本:

红宝石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测试以确保在转换为状态:active后调用post_activate。>

我可以从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

我不确定这是如何工作的-我知道如何将参数设为可选,但我不知道如何选择性地传递参数。

无论如何-如果将参数添加到方法定义中,则测试将通过。但是我不想添加一个我不仅仅用于传递规格的参数。我该如何解决?

我正在使用以下版本:ruby 2.5.5 rails 5.2.3 state_machines-activerecord 0.6.0我有一个带有状态机的模型Foo:类Foo

C0中的[RSpec验证代理]通过当前转换获取validate_arguments!的呼叫。如果在Gemfile中添加post_activate之类的内容,并有条件地将其byebug添加到Rspec的byebug中,则可以看到它:

validate_arguments!

这将使您可以访问actual_args:

@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?

因此,为了解决您的问题,您只需要在回调中添加省略的参数(您已经清楚地知道了):

(byebug) actual_args
[#<StateMachines::Transition ...]

并且要确定为什么下划线使用这种方式,请查看def post_activate(_)

ruby-on-rails rspec-rails state-machine
1个回答
0
投票

C0中的[RSpec验证代理]通过当前转换获取validate_arguments!的呼叫。如果在Gemfile中添加post_activate之类的内容,并有条件地将其byebug添加到Rspec的byebug中,则可以看到它:

© www.soinside.com 2019 - 2024. All rights reserved.