我的模型中有两个共享相同验证的属性
validates :first_name, :last_name, length: {minimum: 2}
现在我测试:first_name
属性如下:
RSpec.describe User, :type => :model do
it 'is invalid if the first name is less than two characters'
user = User.create(
first_name: 'a'
)
expect(user).to have(1).errors_on(:first_name)
end
为了不熟悉我如何设置模型的开发人员,我想明确说明这两个属性'与这样的事情的关系:
it 'is invalid if the first name and/or last name has less than two characters'
user = User.create(
first_name: 'a',
last_name: 'b
)
expect(user).to have(1).errors_on(:first_name, :last_name)
显然这会引发错误:
错误的参数数量(2为0..1)
如果我进行了两次验证,那么同样适用:
validates :first_name, :last_name, length: {minimum: 2}, format: {with: /^([^\d\W]|[-])*$/}
尝试测试2个错误:
it 'is invalid if the first name and/or last name has less than two characters and has special characters'
user = User.create(
first_name: '@',
last_name: '#
)
expect(user).to have(2).errors_on(:first_name, :last_name)
答案 0 :(得分:1)
在RSpec 3.x中,您可以将期望与.and
:
it 'is invalid if the first name and/or last name has less than two characters' do
user = User.create(first_name: 'a', last_name: 'b')
expect(user).to have(1).errors_on(:first_name).and have(1).errors_on(:last_name)
end
查看rspec-expectations文档了解详情。
对于RSpec 2.x,您需要执行以下操作之一:
it 'is invalid if the first name and/or last name has less than two characters' do
user = User.create(first_name: 'a', last_name: 'b')
expect(user).to have(1).errors_on(:first_name) && have(1).errors_on(:last_name)
end
# or
it 'is invalid if the first name and/or last name has less than two characters' do
user = User.create(first_name: 'a', last_name: 'b')
expect(user).to have(1).errors_on(:first_name)
expect(user).to have(1).errors_on(:last_name)
end
它不是很漂亮,但应该有用。
修改强>
OP正在使用rspec-collection_matchers
gem。该gem的自定义匹配器不包含RSpec 3 mixin模块RSpec::Matchers::Composable
,因此#and
方法无法识别。
要绕过这个问题,有几件事要做。最简单的方法是使用上面的&&
技术(在我的RSpec 2.x建议中)。要使用仅 RSpec 3匹配器,您需要使用be_valid
:
it 'is invalid if the first name and/or last name has less than two characters' do
user = User.create(first_name: 'a', last_name: 'b')
expect(user).to_not be_valid
end
当然,这并不像原先预期的那样区分first_name
错误和last_name
错误。要使用be_valid
匹配器执行此操作,您必须将测试分为两个测试:
it 'is invalid if the first name has less than two characters' do
user = User.create(first_name: 'a', last_name: 'abc')
expect(user).to_not be_valid
end
it 'is invalid if the last name has less than two characters' do
user = User.create(first_name: 'abc', last_name: 'a')
expect(user).to_not be_valid
end
答案 1 :(得分:0)
您的测试应如下所示:
it 'invalid length' do
user = User.new(first_name: '@', last_name: '#')
user.valid?
expect(user.errors.count).to eq 2
expect(user.errors[:first_name]).to include "is too short (minimum is 2 characters)"
expect(user.errors[:last_name]).to include "is too short (minimum is 2 characters)"
end
user.valid?
调用将针对将填充错误的验证运行新用户。
进行单元测试这是一个非常详细的测试 - 我强烈推荐shoulda matchers。您只需两行即可测试上述内容:
it { is_expected.to ensure_length_of(:first_name).is_at_least(2) }
it { is_expected.to ensure_length_of(:last_name).is_at_least(2) }