我尝试了几种不同的方法,并且不清楚为什么我写的用户单元测试的各种排列仍然无法测试用户对象的图像属性的文件类型。
这是我现在拥有的......
@model AssignerWebTool.Models.CreateUserModel
@{
ViewBag.Title = "Create User";
}
<head>
<title></title>
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css" rel="stylesheet" />
<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script>
</head>
<body>
<script type="text/javascript">
$(document).ready(function () {
$("help").select2();
});
</script>
<select id="help" class="help">
<option value="AL">Alabama</option>
<option value="WY">Wyoming</option>
</select>
</body>
class User < ApplicationRecord
mount_uploader :image, ImageUploader
validate :image_size_validation
validates_format_of :image, with: %r{\.(png|jpg|jpeg)\Z/}i, message: "image must be png, jpg, or jpeg", allow_nil: true
def image_size_validation
errors[:image] << "should be less than 5MB" if image.size > 5.megabytes
end
end
class ImageUploader < CarrierWave::Uploader::Base
def extension_white_list
%w(jpg jpeg gif png)
end
end
令人费解的是,如果我没有指定 let(:user) { FactoryGirl.create(:user, username: "zoidberg", image: "image.png") }
it "has a valid image file" do
expect(user).to be_valid
expect(user.image).to be_valid
expect(FactoryGirl.build(:user, username: "Farnsworth", image: "image.jpg")).to be_valid
end
,那么测试将失败username: <something>
,尽管它在其他所有测试中都有效并且已经在工厂内构建。
Username is invalid
我也尝试了这个FactoryGirl.define do
factory :user do
first_name Faker::Name.first_name
last_name Faker::Name.last_name
sequence(:username) { |n| "#{n}#{Faker::Internet.user_name}#{Faker::Number.number(5)}#{Faker::Hipster.word}" }
sequence(:email) { |n| "#{n}#{Faker::Hipster.word}#{Faker::Number.number(5)}#{Faker::Internet.email}" }
phone Faker::Base.numerify('##########')
password Faker::Internet.password(6, 20)
state Faker::Address.state_abbr
city Faker::Address.city
image Faker::Avatar.image
sequence(:zip) { |n| "#{n}#{n}#{n}#{n}#{n}" }
seeking_coach true
accept_email true
accept_phone true
end
end
,我认为它会起作用,但显然不会。
答案 0 :(得分:0)
您无法通过简单地使用字符串来表示文件来测试carrierwave - &#34; image.png&#34;。您实际上需要打开文件并将其上传。
File.open(path_to_file) { |f| user.image.store!(f) }
其中path_to_file表示包含您正在测试的文件的文件名的完整路径。
这就是为什么shoulda匹配器也不起作用的原因:
it { should have_valid(:image).when('image.jpg', 'image.png', 'image.jpeg')} # won't work
您需要编写单独的测试来检查每种文件类型。
此外,您应该构建用户对象 - 而不是创建用户对象,因为它在此阶段没有获得有效图像:
let(:user) { FactoryGirl.build(:user, username: "zoidberg") }
it 'with png file it should be valid' do
path_to_png_file = Rails.root + "spec/files/image.png"
File.open(path_to_png_file) { |f| user.image.store!(f) }
expect(user).to be_valid
end
it 'with txt file it should be invalid' do
path_to_txt_file = Rails.root + "spec/files/text.txt"
File.open(path_to_txt_file) { |f| user.image.store!(f) }
expect(user).to_not be_valid
end
当然,您需要根据测试环境设置路径。
您不需要测试实际图像本身 - 它实际上只是您有验证用户的属性。如果图像无效,则用户无效,但您可以测试验证错误,以确保它们与图像相关,如果您愿意。