gpt4 book ai didi

ruby - 如何使用 RSpec 模拟/ stub 文件目录及其内容?

转载 作者:数据小太阳 更新时间:2023-10-29 07:29:32 25 4
gpt4 key购买 nike

前一段时间我问了“How to test obtaining a list of files within a directory using RSpec?”,虽然我得到了一些有用的答案,但我仍然卡住了,因此提出了一个新问题,其中包含有关我正在尝试做的事情的更多细节。

我正在编写我的第一个 RubyGem。它有一个模块,其中包含一个类方法,该方法返回一个数组,该数组包含指定目录中的非隐藏文件列表。像这样:

files = Foo.bar :directory => './public'

该数组还包含一个表示文件元数据的元素。这实际上是从文件内容生成的哈希值的哈希值,其想法是即使更改单个文件也会更改哈希值。

我已经编写了待定的 RSpec 示例,但我真的不知道如何实现它们:

it "should compute a hash of the files within the specified directory"
it "shouldn't include hidden files or directories within the specified directory"
it "should compute a different hash if the content of a file changes"

我真的不想让测试依赖于充当固定装置的真实文件。我如何模拟或 stub 文件及其内容? gem 实现将使用 Find.find,但正如我对其他问题的回答之一所说,我不需要测试该库。

我真的不知道如何编写这些规范,所以非常感谢您的帮助!


编辑:下面的cache方法是我要测试的方法:

require 'digest/md5'
require 'find'

module Manifesto
def self.cache(options = {})
directory = options.fetch(:directory, './public')
compute_hash = options.fetch(:compute_hash, true)
manifest = []
hashes = ''
Find.find(directory) do |path|

# Only include real files (i.e. not directories, symlinks etc.)
# and non-hidden files in the manifest.
if File.file?(path) && File.basename(path)[0,1] != '.'
manifest << "#{normalize_path(directory, path)}\n"
hashes += compute_file_contents_hash(path) if compute_hash
end
end

# Hash the hashes of each file and output as a comment.
manifest << "# Hash: #{Digest::MD5.hexdigest(hashes)}\n" if compute_hash
manifest << "CACHE MANIFEST\n"
manifest.reverse
end

# Reads the file contents to calculate the MD5 hash, so that if a file is
# changed, the manifest is changed too.
def self.compute_file_contents_hash(path)
hash = ''
digest = Digest::MD5.new
File.open(path, 'r') do |file|
digest.update(file.read(8192)) until file.eof
hash += digest.hexdigest
end
hash
end

# Strips the directory from the start of path, so that each path is relative
# to directory. Add a leading forward slash if not present.
def self.normalize_path(directory, path)
normalized_path = path[directory.length,path.length]
normalized_path = '/' + normalized_path unless normalized_path[0,1] == '/'
normalized_path
end
end

最佳答案

我将假设您有某种方法可以获取所有文件然后计算哈希值。让我们调用该方法 get_file_hash 并将其定义如下。

def get_file_hash
file_hash = {}
Find.find(Dir.pwd) do |file|
file_hash[file] = compute_hash(File.read(file))
end
file_hash
end

正如我之前回答的那样,我们将 stub Find.find 和 File.read。但是,我们不会 stub compute_hash 方法,因为您要检查文件哈希。我们将让 compute_hash 方法创建文件内容的实际哈希值。

describe "#get_file_hashes"

......

before(:each)
File.stubs(:find).returns(['file1', 'file2'])
File.stubs(:read).with('file1').returns('some content')
File.stubs(:read).with('file2').returns('other content')
end

it "should return the hash for all files"
@whatever_object.get_file_hashes.should eql({'file1' => "hash you are expecting for 'some content'", 'file2' => "hash you are expecting for 'other content'"})
end

end

为简单起见,我只是读取文件主体并将其传递给 compute_hash 方法并生成哈希。但是,如果您的 compute_hash 方法在文件中使用了一些其他方法来生成哈希。然后您可以将它们 stub 并返回一个值以传递给 compute_hash 方法。虽然,如果 compute_hash 方法是一个公共(public)方法,我更愿意单独测试它,并且只是将其调用存入 get_file_hash 方法中。

关于不显示隐藏文件;您将为此使用一个库来省略私有(private)文件,或者将拥有自己的方法来执行此操作。在前一种情况下,您不需要编写任何测试(假设库经过良好测试),而对于后一种情况,您需要测试单独的方法而不是这个方法。

用于测试在文件内容更改时重新计算文件的哈希值;我猜你一定有某种事件触发了哈希的重新计算。只需调用该事件方法并断言文件哈希匹配即可。

关于ruby - 如何使用 RSpec 模拟/ stub 文件目录及其内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2975191/

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