单元测试从base64字符串打印PNG的方法

霍默·史密斯

我正在尝试测试以下方法,该方法给出了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中进行测试的最佳方法。我知道我应该先写考试,但我仍在学习。Bu基本上我想确保:

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
狂热的

未经测试

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?为真。您最好将其完全移出方法,并传递到方法路径的根部分,然后处理调用代码或初始化程序中环境之间的差异。

您将如何重写该函数,以使测试在所有环境中都有意义?

有几种方法。您可以在初始化时添加一个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文件中读取值,或使用诸如simpleconfig之类的gem

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章