首页 > 解决方案 > 使用 shell_out 进行 Chef 库测试

问题描述

我正在为 Chef 编写自定义资源。该资源用于设置 sysctl 值。我基本上使用的是 Chef sysctl 代码并对其进行了一些限制。我们不信任公司的所有用户:P

我正在尝试将大部分代码放在库帮助器模块中,以便更轻松地测试代码。我不确定这是否是最佳做法。让我知道这是否是不好的做法。

无论如何,我遇到的问题是尝试测试我的库代码。每当我尝试模拟 shell_out 命令时,我总是会收到以下错误。

1) Sysctl::Helpers.set_sysctl_param
     Failure/Error: subject.set_sysctl_param("key1", "value1")

     NoMethodError:
       undefined method `shell_out!' for Sysctl::Helpers:Module

图书馆代码

module Sysctl
  module Helpers
    include Chef::Mixin::ShellOut
    def self.set_sysctl_param(key, value)
      shell_out!("sysctl -w \"#{key}=#{value}\"")
    end
  end
end

测试

require 'spec_helper'
describe Sysctl::Helpers do
  describe '.set_sysctl_param' do
    let(:shellout) { double(run_command: nil, error!: nil, stdout: '', stderr: double(empty?: true)) }
    before do
      allow(Chef::Mixin::ShellOut).to receive(:new).and_return(shellout)
    end

    it do
      subject.set_sysctl_param("key1", "value1")
      expect(:shellout).to receive(:run_command).with("sysctl -w \"key1=value1\"")
    end
  end
end

我很感激你能给我的任何帮助或建议。

谢谢!

标签: rspecchef-infrachefspec

解决方案


包含模块时,您将模块方法添加为实例方法。但是您尝试shell_out在类方法中访问。您实际上需要使用 Chef::Mixin::ShellOut扩展您的模块。这样,ShellOut 方法将被添加为类方法。

module Sysctl
  module Helpers
    extend Chef::Mixin::ShellOut  # replace include with extend
    def self.set_sysctl_param(key, value)
      shell_out!("sysctl -w \"#{key}=#{value}\"")
    end
  end
end

更多关于这个Ruby 中的 include 和 extend 有什么区别?


推荐阅读