我正在尝试测试以下方法,它给出了base64字符串,它会输出一个PNG:
def self.decode64_to_png(src)
if (src.start_with? "data:image/png;base64")
png = Base64.decode64(src['data:image/png;base64,'.length .. -1])
png_logo_uuid = SecureRandom.urlsafe_base64(nil,false)
if Rails.env.production?
src = "#{Rails.root}/tmp/#{png_logo_uuid}.png"
File.open(src, 'wb') { |f| f.write(png) }
else
src = "#{Rails.root}/public/images/#{png_logo_uuid}.png"
File.open(src, 'wb') { |f| f.write(png) }
end
return src
end
end
但我对测试很陌生,我正在试图找出在rspec中测试这个的最佳方法。我知道我应该先写测试,但我还在学习。基本上我想确保:
1 - 给定正确的base64字符串,创建一个图像并返回src 2 - 如果base64不正确,则返回nil。
这是我到目前为止所做的测试:
describe ".decode64_to_png" do
it 'returns a path if the source is a correct base64 string' do
File.stub(:open) { true }
src = "data:image/png;base64,iVBORw0KGg"
ImageManipulation.decode64_to_png(src).should_not be_nil
end
it 'returns nil if the source is not a correct base64 string' do
File.stub(:open) { true }
src = "asdasdasdata:image/png;base64,iVBORw0KGg"
ImageManipulation.decode64_to_png(src).should be_nil
end
end
答案 0 :(得分:1)
未测试
describe ".decode64_to_png" do
let(:payload) { "iVBORw0KGg" }
let(:uuid) { "uuid" }
let(:file_args) { "#{Rails.root}/tmp/uuid.png" }
context "when src is valid" do
let(:src) { "data:image/png;base64,#{payload}" }
before do
Base64.should_receive(:decode64).with(payload)
SecureRandom.should_receive(:urlsafe_base64).with(nil, false).and_return(uuid)
Rails.stub_chain(:env, :production?) { true }
end
it "writes the image to a file" do
File.should_receive(:open).with(file_args)
ImageManipulation.decode64_to_png(src)
end
it "returns the file path" do
File.stub(:open)
ImageManipulation.decode64_to_png(src).should eq(file_args)
end
end
context "when src is invalid" do
let(:src) { "asdadasdada:data:image/png;base64,#{payload}" }
it "does not write the image" do
File.should_not_receive(:open)
ImageManipulation.decode64_to_png(src)
end
it "returns nil" do
ImageManipulation.decode64_to_png(src).should be_nil
end
end
end
测试副作用(即写入文件)似乎比返回值更重要;你应该测试两者。
请注意,最后一个示例失败,因为当输入无效时,方法返回输入,而不是返回nil。我认为该方法应该引发异常。
另请注意,这仅测试Rails.env.production?
的代码路径为true。你最好完全从方法中移出它并将路径的根部分传递给方法,然后处理调用代码或初始化程序中环境之间的差异。
您将如何重写该功能,以便测试在所有方面都有意义 环境?
有几种方法;你可以添加一个Settings类,并在初始化时将图像文件夹路径粘贴在其中:
# lib/settings.rb
class Settings
include Singleton
attr_accessor :image_path
end
# config/initializers/settings.rb
case Rails.env
when "production"
Settings.instance.image_path = "#{Rails.root}/tmp"
else
Settings.instance.image_path = "#{Rails.root}/public/images"
end
替换
if Rails.env.production?
src = "#{Rails.root}/tmp/#{png_logo_uuid}.png"
File.open(src, 'wb') { |f| f.write(png) }
else
src = "#{Rails.root}/public/images/#{png_logo_uuid}.png"
File.open(src, 'wb') { |f| f.write(png) }
end
与
src = File.join(Settings.instance.image_path, "#{png_logo_uuid}.png")
添加到规范
Settings.stub_chain(:instance, image_path) { "#{Rails.root}/tmp" }
您还可以阅读YAML文件as described here中的值,或使用像simpleconfig这样的gem。