gpt4 book ai didi

unit-testing - 如何创建在另一个配方中定义的虚拟资源而不在测试运行中包含另一个配方?

转载 作者:行者123 更新时间:2023-12-04 04:57:53 27 4
gpt4 key购买 nike

我有以下厨师食谱:

# recipes/default.rb

include_recipe 'my-cookbook::another_recipe'

execute 'Do some stuff' do
command "echo some stuff"
action :run
end

template "my_dir/my_file.txt" do
source "my_file.txt.erb"
owner 'myuser'
group 'mygroup'
notifies :restart, resources(:service => 'my-service'), :delayed
end

和另一个食谱
# recipes/another_recipe.rb

service 'my-service' do
start_command "my-service start"
stop_command "my-service stop"
supports :start => true, :stop => true
action :nothing
end

现在我想写一个 Chefspec 单元测试到 default孤立的食谱。所以我写了这个:
# spec/unit/recipes/default_spec.rb

require 'rspec/core'
require 'chefspec'

describe 'my-cookbook::default' do
let(:chef_run) { ChefSpec::SoloRunner.converge(described_recipe) }

before do
allow_any_instance_of(Chef::Recipe).to receive(:include_recipe).with('my-cookbook::another_recipe')
end

it "Does the stuff" do
expect(chef_run).to run_execute("echo some stuff")
end

end

我如何创建 another_recipe 中定义的服务的虚拟对象为了防止这种情况发生:
 11:    group 'mygroup'
12>> notifies :restart, resources(:service => 'my-service'), :delayed
13: end
...
Failure/Error: let(:chef_run) { ChefSpec::SoloRunner.converge(described_recipe) }
Chef::Exceptions::ResourceNotFound:
Cannot find a resource matching service[my-service] (did you define it first?)

我知道这可能是一个糟糕的设计和一个相当简单的新手问题,但我真的被困在这里,我的情况是这样的:
  • 我有几个月的 Chef 经验,但除此之外没有 Ruby 经验
  • 这是最初编写时没有任何单元测试的生产代码
  • 真正的代码包含更多的东西,这里的这些代码片段只是特定问题的模型
  • 我的任务是修改 default配方,所以我想添加一些单元测试来验证我的修改是否有效并且不会破坏现有功能
  • 在这一点上,我想尽可能避免修改任何其他文件(即 another_recipe )
  • 如果我让测试也运行 another_recipe那么我需要模拟并设置太多它需要的其他东西

  • 谢谢 :)
    k6ps

    最佳答案

    我的观点:

    您应该允许 another_recipe 运行并执行使其收敛所需的操作。如果不是,您就不能真正相信您的测试,因为它们不是针对运行中会发生的情况而完成的。

    无论如何,解决您的案例的方法:

    好吧,您可以在您的食谱中添加一个“模拟食谱”,它将定义您需要在没有太多 stub /模拟调用的情况下测试您的食谱的无操作资源。

    假设它被称为“spec-receipe.rb”,它看起来像:

    service 'my-service' do
    action :nothing
    end

    然后你运行你的测试,包括这个“规范配方”,如下所示:
    let(:chef_run) { ChefSpec::SoloRunner.converge('my_cookbook::spec-recipe',described_recipe) }

    另一种方法可能是 include_recipe 'my_cookbook::spec-recipe' if defined?(ChefSpec)所以这个配方将只包含在chefspec运行中而不包含在正常运行中,您不必在运行程序声明中指定它。

    关于unit-testing - 如何创建在另一个配方中定义的虚拟资源而不在测试运行中包含另一个配方?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29029152/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com