Rspec在测试中操纵上传大小验证器

时间:2019-06-12 09:05:29

标签: ruby-on-rails ruby-on-rails-4 rspec rspec-rails

在我的attachment模型上,我得到了以下验证:

validates_attachment_size :data, less_than: 8.megabyte, message: :data_file_size_error

它正在做我需要的一切,但是为了测试它,现在我实际上必须在磁盘空间上存储一个9 MB的文件。由于我的应用程序非常庞大,因此我希望避免这样做。

所以我的想法是-我可以操纵验证方法本身,但仅用于测试。假设将context块大小内的验证设置为5 KB,尝试上传6 KB文件,然后将其恢复为正常?

(记录:这个过程很麻烦-我正在创建一封传入的电子邮件,然后向其中添加一个文件,然后尝试导入此文件。这就是为什么我想将文件保持较小的原因。另一个我尝试的选项是stub文件大小,但是在集成测试中,Rspec仍将访问实际大小,因此导致测试失败。

2 个答案:

答案 0 :(得分:1)

我认为您不能轻易对文件大小进行存根处理,因为在类加载期间仅对文件大小进行了一次检查。但是,有很多方法可以解决此问题:

  1. 您可以在添加到.gitignore的某个目录中保留9MB的文件,例如tmp/testfiles,在运行规范时,您可以生成此文件(如果不存在)。这样,您将只生成一次,因此以后的测试将更快(无需每次都生成),并且不会将其保存在存储库中

  2. 您可以使less_than选项动态化,即执行类似less_than: -> { maximum_file_size }的操作,然后定义方法def self.maximum_file_size; 8.megabyte; end。然后,您应该可以轻松地将其存根,因为最大大小是在每次上传时确定的。缺点是您仅出于测试目的添加了动态选项,但这会影响您的生产代码。

  3. 您可以编写一个单元测试,以验证是否调用了正确的大小。 it { should validate_attachment_size(:image).less_than(5.megabytes) }。然后,您将不会执行实际的文件上传,但是只要您信任您的库,此测试就足够了。 (代码假定您使用的是Paperclip,其他库看起来可能有所不同。)

答案 1 :(得分:0)

实际上,我认为此解决方案非常优雅,这是我最终使用的解决方案:

validator = Profile::Attachment._validators[:data].find{|validator| validator.options[:less_than]}
validator.stubs(:options).returns({less_than: 2500, message: :data_file_size_error}) # 2500 Bytes are ~ 2,44 KB

使用此代码,我可以上载3KB的文件,结果是验证失败。