1

如果我在配方中使用模板资源

template '/home/user1/foo' do
  source 'bar'
end

我使用 chefspec/rspec 进行测试

...
expect(chef_run).to render_file('/home/user1/foo')
expect(chef_run).to create_template('/home/user1/foo')
expect(chef_run).to create_template('/home/user1/foo').with_source 'bar
...

所有测试都通过......
即使食谱中缺少源模板“bar”。

这给我留下了一本食谱,它通过了我能想到的所有测试,但是当我尝试运行它时会失败。Cookbook_file 资源也是如此。

我可以看到如何测试资源可以查找源文件的所有位置(根据资源文档中的“文件特定性”部分)是如何成为蠕虫的,但它似乎仍然是测试工具中的一个大漏洞.

我是否忽略了一种测试源文件是否存在的方法,或者在更基本的层面上做错了什么?还是这就是它的本来面目,每个人都与之共存?

4

1 回答 1

1

好的,这有点令人费解,但它有效。对于这个配方片段:

template '/home/user1/foo' do
  source 'bar'
end

当不存在模板源文件“bar”时,尽管缺少源文件,但这个 Chefspec 期望通过。

expect(chef_run).to render_file('/home/user1/foo')

但这失败了Chef::Exceptions::FileNotFound,提供了一种测试源是否存在的方法:

expect(chef_run).to render_file('/home/user1/foo').with_content(/.*/)

显然,with_content()方法强制解析源引用,以便匹配器可以呈现文件以进行比较。如果您并不真正关心匹配特定内容,/.*/请匹配任何内容,以便您仍然可以测试源是否存在。

更多,针对@ user3670408 的问题...

Chefspec 必须将文件内容呈现为字符串以与.with_content()参数进行比较问题似乎是您正在使用的实际说明书文件是二进制文件。发生的事情可能是这样的:

# Create a bad UTF-8 file
File.open('bad_utf8.bin', mode: 'wb') { |file| file.putc(0xfe) }
# Read contents and try to use the resulting string
File.read('bad_utf8.bin').match(/.*/)
# Result is:  ArgumentError: invalid byte sequence in UTF-8

所以一般来说,这个.with_content(/.*/)技巧不适用于二进制食谱文件,除非你做一些像捕捉 ArgumentError 这样的黑客行为。

于 2015-02-17T02:11:24.440 回答