【问题标题】:Mocking Files during a ChefSpec run在 ChefSpec 运行期间模拟文件
【发布时间】:2015-07-31 16:38:52
【问题描述】:

我创建了一个 Chef 资源,它“扩展”了 chef 的部署资源。基本思想是检查要部署的源中是否存在类似于机制deploy/after_restart.rb 的文件deploy/crontab,并从中创建cronjobs。

虽然此机制按应有的方式工作(请参阅https://github.com/fh/easybib-cookbooks/blob/t/cron-tests/easybib/providers/deploy.rb#L11-L14),但我正在努力进行基于 ChefSpec 的测试。我目前正在尝试使用 FakeFS 创建模拟 - 但是当我在 Chef 运行之前模拟文件系统时,运行失败,因为没有找到食谱,因为它们在模拟的文件系统中不存在。如果我不这样做,则显然找不到模拟文件deploy/crontab,因此提供者不会做任何事情。我目前的做法是在 chef_run 中直接在 runner.converge(described_recipe) 之前触发 FakeFS.activate!。

我很想听听一些关于如何在此处进行适当测试的建议:是否有可能仅在部署资源运行之前直接启用 FakeFS,或者仅部分模拟文件系统?

【问题讨论】:

    标签: rspec chef-infra chefspec


    【解决方案1】:

    我在存根文件系统类时遇到了类似的问题。我解决这个问题的方法如下。

    ::File.stub(:exists?).with(anything).and_call_original
    ::File.stub(:exists?).with('/tmp/deploy/crontab').and_return true
    
    open_file = double('file')
    allow(open_file).to receive(:each_line).and_yield('line1').and_yield('line2')
    
    ::File.stub(:open).and_call_original
    ::File.stub(:open).with('/tmp/deploy/crontab').and_return open_file
    

    【讨论】:

    • 是的,这行得通-但我的问题是我还必须模拟文件的内容,因为我必须读取/解析内容:github.com/fh/easybib-cookbooks/blob/t/cron-tests/easybib/…
    • 类似地,您可以执行以下操作。 ::File.stub(:open).with(anything).and_call_original ::File.stub(:open).with('/tmp/deploy/crontab').and_return 'content'
    • 不,因为这是一个字符串,并且(根据错误)不提供 each_line 方法:)
    • 您可以模拟 File.open 返回的打开文件对象吗?
    • 抱歉耽搁了。它主要工作;)我在这里上传了我当前测试设置的缩小版本:github.com/fh/chefspec-debugging 问题是它显然永远不会达到github.com/fh/chefspec-debugging/blob/master/easybib/providers/… - each_line 调用的模拟返回值似乎是错误的,因为它确实不执行循环。不知道为什么,也许你有一个想法。
    【解决方案2】:

    由于punkle的解决方案在语法上已被弃用并且缺少一些部分,我将尝试提供一个新的解决方案:

    require 'spec_helper'
    
    describe 'cookbook::recipe' do
    
      let(:chef_run) { ChefSpec::SoloRunner.converge(described_recipe) }
    
    
      file_content = <<-EOF
    ...here goes your
    multiline
    file content
    EOF
    
      describe 'describe what your recipe should do' do
    
        before(:each) do
          allow(File).to receive(:exists?).with(anything).and_call_original
          allow(File).to receive(:exists?).with('/path/to/file/that/should/exist').and_return true
          allow(File).to receive(:read).with(anything).and_call_original
          allow(File).to receive(:read).with('/path/to/file/that/should/exist').and_return file_content
        end
    
        it 'describe what should happen with the file...' do
          expect(chef_run).to #...
        end
      end
    
    end
    

    【讨论】:

      猜你喜欢
      • 2014-04-26
      • 2020-06-05
      • 2011-10-10
      • 2022-01-19
      • 1970-01-01
      • 2020-09-15
      • 1970-01-01
      • 2015-02-03
      • 1970-01-01
      相关资源
      最近更新 更多