2

我对 Rspec 非常陌生,并且正在尝试使用以下骨架测试 Ruby 脚本(它是厨师食谱)。

def foo1
   # do stuff
   list_of_names  # returns a list
end

def foo2(list_of_names)
  # do stuff
  counter = [...]
  .
  .
  counter_by_name_hash   # returns a hash
end

def main
  list = foo1
  counter_by_name_hash = foo2(list)
end

main

我想断言,当一个空列表作为参数传递时,函数 foo2 返回一个空哈希,当一个有效的非空列表传递给它时,它返回一个非空哈希。

我尝试了以下两种方法:

首先:在这里我得到NoMethodError - undefined method foo2 错误。不确定如何声明subject,因为方法 foo2 不在类中,它在作为 Chef 配方运行的 Ruby 脚本中。

it 'has valid list of names as input and returns valid hash' do
    valid_hash = {...}
    expect(subject.foo2(valid_list_of_names)).to eq(valid_hash)
end

第二:不确定这是否是断言返回值,因为即使我在 and_return 部分指定了意外值,它也不会引发错误。

it 'has valid list of names as input and returns valid hash' do
    valid_hash = {...}
    expect(subject).to receive(:foo2).with(valid_list_of_names).and_return(valid_hash)
    subject.foo2(valid_list_of_names)
end

我的问题是,断言函数 foo2 的返回值的正确方法是什么?如果方法 foo2 不在 Ruby 类中而是在 Recipe 中,我应该如何在我的规范文件中声明 Subject?任何输入或帮助表示赞赏。

4

1 回答 1

1

编辑:

我不熟悉 Chef,但您可以在 rspec 测试中从您的存储库中获取一个文件并访问其中的方法。像这样:

# path/to/chef_file
def foo1
   # do stuff
   list_of_names  # returns a list
end

def foo2(list_of_names)
  # do stuff
  counter = [...]
  .
  .
  counter_by_name_hash   # returns a hash
end

def main
  list = foo1
  counter_by_name_hash = foo2(list)
end


# spec/chef_tests/my_test.rb
require 'path/to/chef_file'

describe 'Chef Tests' do
  before do
    valid_list_of_names = [...]
    valid_hash = {...}
  end

  it 'foo1 returns a valid list of names' do
    expect( foo1 ).to eq valid_list_of_names
  end

  it 'foo2 returns a valid_hash with a valid_list_of_names as input' do
    expect(foo2(valid_list_of_names)).to eq(valid_hash)
  end

end

第一个答案:

看起来您正在为您的课程使用单例模式。在这种情况下,您的课程和测试可能看起来像这样,它应该可以工作。

class SomeClass
  class<<self
    def foo1
       # do stuff
       list_of_names  # returns a list
    end

    def foo2(list_of_names)
      # do stuff
      counter = [...]
      .
      .
      counter_by_name_hash   # returns a hash
    end

    def main
      list = foo1
      counter_by_name_hash = foo2(list)
    end
  end
end

describe SomeClass do
  before do
    valid_list_of_names = [...]
    valid_hash = {...}
  end

  it 'has valid list of names as input and returns valid hash' do
    expect(SomeClass.foo2(valid_list_of_names)).to eq(valid_hash)
  end

  it 'has valid list of names as input and returns valid hash' do
      expect(SomeClass).to receive(:foo2).with(valid_list_of_names).and_return(valid_hash)
      SomeClass.foo2(valid_list_of_names)
  end
end

显然,我在这里做了一个假设,但是如果您使用更稳定的 ruby​​ 方式来拥有一个实例,那么您只需初始化对象,@my_instance = SomeClass.create(...)然后从实例中检查您的方法。像这样:

expect( @my_instance.foo2( valid_list_of_names ) ).to eq valid_hash
于 2017-02-26T01:24:21.737 回答