gpt4 book ai didi

ruby-on-rails - 模型中的 Rspec Ruby on Rails 测试文件系统

转载 作者:太空宇宙 更新时间:2023-11-03 16:30:55 24 4
gpt4 key购买 nike

我有一个模型,它有一种方法,可以从特定位置开始查看文件系统,以查找与特定正则表达式匹配的文件。这是在 after_save 回调中执行的。我不确定如何使用 Rspec 和 FactoryGirl 对此进行测试。我不确定如何使用 FakeFS 之类的东西,因为该方法在模型中,而不是测试或 Controller 中。我指定了在我的 FactoryGirl 工厂中开始的位置,所以我可以将其更改为由测试在设置子句中创建的假目录?我可以模拟目录吗?我认为可能有几种不同的方法可以做到这一点,但哪种方法最有意义?

谢谢!

  def ensure_files_up_to_date
files = find_assembly_files
add_files = check_add_assembly_files(files)
errors = add_assembly_files(add_files)
if errors.size > 0 then
return errors
end
update_files = check_update_assembly_files(files)
errors = update_assembly_files(update_files)
if errors.size > 0 then
return errors
else
return []
end
end

def find_assembly_files
start_dir = self.location
files = Hash.new
if ! File.directory? start_dir then
errors.add(:location, "Directory #{start_dir} does not exist on the system.")
abort("Directory #{start_dir} does not exist on the system for #{self.inspect}")
end
Find.find(start_dir) do |path|
filename = File.basename(path).split("/").last
FILE_TYPES.each { |filepart, filehash|
type = filehash["type"]
vendor = filehash["vendor"]
if filename.match(filepart) then
files[type] = Hash.new
files[type]["path"] = path
files[type]["vendor"] = vendor
end
}
end
return files
end

def check_add_assembly_files(files=self.find_assembly_files)
add = Hash.new
files.each do |file_type, file_hash|
# returns an array
file_path = file_hash["path"]
file_vendor = file_hash["vendor"]
filename = File.basename(file_path)
af = AssemblyFile.where(:name => filename)

if af.size == 0 then
add[file_path] = Hash.new
add[file_path]["type"] = file_type
add[file_path]["vendor"] = file_vendor
end
end
if add.size == 0 then
logger.error("check_add_assembly_files did not find any files to add")
return []
end
return add
end

def check_update_assembly_files(files=self.find_assembly_files)
update = Hash.new
files.each do |file_type, file_hash|
file_path = file_hash["path"]
file_vendor = file_hash["vendor"]
# returns an array
filename = File.basename(file_path)
af = AssemblyFile.find_by_name(filename)

if !af.nil? then
if af.location != file_path or af.file_type != file_type then
update[af.id] = Hash.new
update[af.id]['path'] = file_path
update[af.id]['type'] = file_type
update[af.id]['vendor'] = file_vendor
end
end
end
return update
end

def add_assembly_files(files=self.check_add_assembly_files)
if files.size == 0 then
logger.error("add_assembly_files didn't get any results from check_add_assembly_files")
return []
end
asm_file_errors = Array.new
files.each do |file_path, file_hash|
file_type = file_hash["type"]
file_vendor = file_hash["vendor"]
logger.debug "file type is #{file_type} and path is #{file_path}"
logger.debug FileType.find_by_type_name(file_type)
file_type_id = FileType.find_by_type_name(file_type).id
header = file_header(file_path, file_vendor)
if file_vendor == "TBA" then
check = check_tba_header(header, file_type, file_path)
software = header[TBA_SOFTWARE_PROGRAM]
software_version = header[TBA_SOFTWARE_VERSION]
elsif file_vendor == "TBB" then
check = check_tbb_header(header, file_type, file_path)
if file_type == "TBB-ANNOTATION" then
software = header[TBB_SOURCE]
else
software = "Unified"
end
software_version = "UNKNOWN"
end

if check == 0 then
logger.error("skipping file #{file_path} because it contains incorrect values for this filetype")
asm_file_errors.push("#{file_path} cannot be added to assembly because it contains incorrect values for this filetype")
next
end

if file_vendor == "TBA" then
xml = header.to_xml(:root => "assembly-file")
elsif file_vendor == "TBB" then
xml = header.to_xml
else
xml = ''
end

filename = File.basename(file_path)
if filename.match(/~$/) then
logger.error("Skipping a file with a tilda when adding assembly files. filename #{filename}")
next
end
assembly_file = AssemblyFile.new(
:assembly_id => self.id,
:file_type_id => file_type_id,
:name => filename,
:location => file_path,
:file_date => creation_time(file_path),
:software => software,
:software_version => software_version,
:current => 1,
:metadata => xml
)

assembly_file.save! # exclamation point forces it to raise an error if the save fails
end # end files.each

return asm_file_errors
end

最佳答案

快速回答:您可以像其他任何方法一样 stub 模型方法。 stub 模型的特定实例,然后 stub find 或任何返回它的东西,或者 stub any_instance 到如果你不想担心哪个模型是涉及。像这样的东西:

it "does something" do
foo = Foo.create! some_attributes
foo.should_receive(:some_method).and_return(whatever)
Foo.stub(:find).and_return(foo)
end

真正的答案是您的代码太复杂而无法有效测试。您的模型甚至不应该知道文件系统的存在。该行为应封装在其他类中,您可以独立测试这些类。您的模型的 after_save 然后可以只调用该类的单个方法,测试是否调用该单个方法会容易得多。

您的方法也很难测试,因为它们试图做的事情太多了。所有这些条件逻辑和外部依赖性意味着您必须进行大量模拟才能获得您可能想要测试的各个位。

这是一个很大的话题,一个好的答案远远超出了这个答案的范围。从 Wikipedia article on SOLID 开始并从那里阅读一些将关注点分离到单独的类和使用微小的组合方法背后的推理。给你一个大概的想法,一个有多个分支或超过 10 行代码的方法太大了;超过 100 行代码的类太大了。

关于ruby-on-rails - 模型中的 Rspec Ruby on Rails 测试文件系统,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16110677/

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