【问题标题】:How can I check chefspec/unit test for following code of my recipe我如何检查chefspec/单元测试以获取我的食谱的以下代码
【发布时间】:2023-06-11 12:21:01
【问题描述】:

我正在尝试为我的食谱编写chefspec/单元测试。我面临问题。我需要为下面的代码编写单元测试用例。如果我注释了代码的最后一条语句,则测试会成功执行,但我也必须捕获该语句,因为它是正确的编写方式。感谢您的帮助。

powershell_script 'Delete ISO from temp directory' do
    code <<-EOH
            [System.IO.File]::Delete("#{iso_path}")
            [System.IO.File]::Delete("#{config_path}")
            EOH
    guard_interpreter :powershell_script
    only_if { File.exists?(iso_path)}
end

【问题讨论】:

  • 据我了解,您正试图删除一些文件。 Chef 有 file 资源,您不需要 powershell。
  • @DracoAter 我只想从临时目录中删除 ISO,前提是它存在。我已使用 powershell 资源对该块进行单元测试,它工作正常,但我也必须抓住条件才能正确编写单元测试
  • 这正是file 资源所做的。如果文件存在,它将删除文件。您应该始终更喜欢现有的幂等资源(如文件、目录、模板)而不是非幂等资源(如执行、bash、powershell_script)。

标签: unit-testing chef-infra chef-recipe cookbook chefspec


【解决方案1】:

首先,您的代码没有意义。您有一个 guard_interpreter 集,但您的保护子句是一个 Ruby 代码块,而不是命令字符串。除此之外,只需像其他任何东西一样测试它。如果您的意思是具体如何测试文件存在和不存在,您可以使用rspec-mocks 设置File.exists? 以返回一个固定值。

【讨论】:

    【解决方案2】:

    首先。如果你只需要删除一个文件,根据这种情况的代码,你应该使用file资源。

    [iso_path, config_path].each do |path|
      file path do
        action :delete
      end
    end
    

    File 是幂等资源。这意味着 Chef 会检查您是否应该更改资源。在这种情况下,Chef 将删除该文件,前提是该文件存在。

    Powershell_script(以及所有其他 script 资源)是非幂等的。这意味着,您已经通过提供guard 来检查自己是否应该执行资源。 Guard 是 only_ifnot_if 块。您应该删除 guard_interpreter :powershell_script 行,因为您实际上是在警卫中编写 ruby​​。

    powershell_script 'Delete ISO from temp directory' do
      code <<-EOH
        [System.IO.File]::Delete("#{iso_path}")
        [System.IO.File]::Delete("#{config_path}")
        EOH
      only_if { File.exists?(iso_path) }
    end
    

    现在开始测试。测试file 资源很容易,因为我知道您已经可以做到这一点。但是测试powershell_script 更难:你必须存根File.exists?(iso_path) 调用。你可以这样做:

    describe 'cookbook::recipe' do
      context 'with iso file' do
        let! :subject do
          expect( ::File ).to receive( :exists? ).with( '<iso_path_variable_value>' ).and_return true
          allow( ::File ).to receive( :exists? ).and_call_original
          ChefSpec::Runner.new( platform: 'windows', version: '2008R2' ).converge described_recipe
        end
    
        it { shold run_powershell_script 'Delete ISO from temp directory' }
      end
    
      context 'without iso file' do
        let! :subject do
          expect( ::File ).to receive( :exists? ).with( '<iso_path_variable_value>' ).and_return false
          allow( ::File ).to receive( :exists? ).and_call_original
          ChefSpec::Runner.new( platform: 'windows', version: '2008R2' ).converge described_recipe
        end
    
        it { shold_not run_powershell_script 'Delete ISO from temp directory' }
      end
    end
    

    与测试file 资源相比,您知道您需要做多少工作吗?

    【讨论】:

      最近更新 更多