RSpec如何测试传递给方法的参数数据类型

时间:2017-04-22 03:47:12

标签: ruby-on-rails ruby rspec tdd bdd

我需要测试传递的参数类型是否为整数。这是我的测试规范:

require 'ball_spin'

RSpec.describe BallSpin do
  describe '#create_ball_spin' do
    subject(:ball_spin) { BallSpin.new }
    it 'should accept an integer argument' do
      expect(ball_spin).to receive(:create_ball_spin).with(an_instance_of(Integer))
      ball_spin.create_ball_spin(5)
    end
  end
end

我的代码:

class BallSpin
  def create_ball_spin n
    "Created a ball spin #{n} times" if n.is_a? Integer
  end
end

提前致谢

更新

为使用旧的RSpec语法道歉,下面我更新了我的代码以使用最新的代码:

it 'should accept an integer argument' do
  expect(ball_spin).to receive(:create_ball_spin).with(an_instance_of(Integer))
  ball_spin.create_ball_spin(5)
end

3 个答案:

答案 0 :(得分:3)

您可以向receive添加一个块以检查方法参数:

expect(ball_spin).to receive(:create_ball_spin) do |arg|
  expect(arg.size).to be_a Integer
end

您可以在rspec-mocks文档的Arbitrary Handling section中找到详细信息。

更新:您也可以使用should语法使用相同的方法:

ball_spin.should_receive(:create_ball_spin) do |arg|
  arg.should be_a Integer
end

答案 1 :(得分:1)

我认为原因是5是Fixnum的一个实例,而不是Integer:

2.2.1 :005 > 5.instance_of?(Fixnum)
  => true 
2.2.1 :006 > 5.instance_of?(Integer)
  => false 

更新: 好的,我已经尝试过您的代码,问题是Integer而不是Fixnum。这是正确的断言:

RSpec.describe BallSpin do
  describe '#create_ball_spin' do
    subject(:ball_spin) { BallSpin.new }
    it 'should accept an integer argument' do
      expect(ball_spin).to receive(:create_ball_spin).with(an_instance_of(Fixnum))
      ball_spin.create_ball_spin(5)
    end
  end
end

答案 2 :(得分:0)

receive匹配器的用例是指定方法由某人调用。但值得注意的是,匹配器本身并不会调用该方法,也不会测试方法是否存在,或者可能的参数列表是否与给定模式匹配。

您的代码似乎根本没有调用该方法。应该通过的简单测试可能如下所示:

subject(:ball_spin) { BallSpin.new }

it 'is called with an integer argument' do
  ball_spin.should_receive(:create_ball_spin).with(an_instance_of(Integer))
  ball_spin.create_ball_spin(5) # method called
end

it 'is not called' do
  ball_spin.should_not_receive(:create_ball_spin)
  # method not called
end

请参阅Argument Matcher

部分

您是否使用旧的RSpec语法,可能需要考虑将测试套件更新为新的expect语法。