ruby - 使用 Rspec 断言 Ruby(Chef Recipe)中方法的返回值

标签 ruby rspec chef-infra chef-recipe chefspec

我是 Rspec 的新手,正在尝试使用以下框架测试 Ruby 脚本(它是 Chef Recipe )。

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 不在类中,它在 Ruby 中作为 Chef Recipe 运行的脚本。

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?感谢任何输入或帮助。

最佳答案

编辑:

我不熟悉 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)使用单例模式。在这种情况下,您的类和测试可能看起来像这样并且它应该可以工作。

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

关于ruby - 使用 Rspec 断言 Ruby(Chef Recipe)中方法的返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42463296/

相关文章:

ruby - 为什么 "foo".class === String 返回 false?

ruby-on-rails - RSpec Mailer 测试匹配失败

ssl - Chef SSL 验证失败

ruby - 通过立即散列返回抽头散列有好处吗?

ruby-on-rails - POST 方法不适用于 rack-cors rails 4

ruby - 使用 RMagick 读取图像时设置密度

ruby - stub 实例方法在使用 minitest 的第二次调用时返回值不同

ruby-on-rails - factory_girl + rspec 似乎不会在每个示例后回滚更改

Git 使用 Chef git 资源部署主分支或特定提交或标记

amazon-web-services - 在 Chef 配方中获取 EC2 实例名称