用于测试验证错误的简单语法

时间:2009-09-26 15:53:45

标签: ruby-on-rails unit-testing validation

我正在寻找干净和简短的代码来测试Rails Unittests中的验证。

目前我做的事情

test "create thing without name" do
    assert_raise ActiveRecord::RecordInvalid do
        Thing.create! :param1 => "Something", :param2 => 123
    end
end

我想还有一种更好的方法可以显示验证信息吗?

解决方案:

我目前没有额外框架的解决方案是:

test "create thing without name" do
    thing = Thing.new :param1 => "Something", :param2 => 123
    assert thing.invalid?
    assert thing.errors.on(:name).any?
end

6 个答案:

答案 0 :(得分:5)

您没有提到您正在使用的测试框架。许多宏具有使测试活动记录变得轻而易举的宏。

如果不使用任何测试助手,这是“漫长的道路”:

thing = Thing.new :param1 => "Something", :param2 => 123
assert !thing.valid?
assert_match /blank/, thing.errors.on(:name)

答案 1 :(得分:2)

我正在使用Rails 2.0.5,当我想断言模型验证失败时,我会检查errors.full_messages method,并将其与预期消息数组进行比较。

created = MyModel.new
created.field1 = "Some value"
created.field2 = 123.45
created.save

assert_equal(["Name can't be blank"], created.errors.full_messages)

断言验证成功,我只是比较一个空数组。您可以执行非常类似的操作,以检查创建或更新请求后Rails控制器是否没有错误消息。

assert_difference('MyModel.count') do
  post :create, :my_model => {
    :name => 'Some name'
  }
end

assert_equal([], assigns(:my_model).errors.full_messages)
assert_redirected_to my_model_path(assigns(:my_model))

答案 2 :(得分:1)

还要尝试accept_values_for gem。 它允许做这样的事情:

describe User do

  subject { User.new(@valid_attributes)}

  it { should accept_values_for(:email, "john@example.com", "lambda@gusiev.com") }
  it { should_not accept_values_for(:email, "invalid", nil, "a@b", "john@.com") }
end

通过这种方式,您可以轻松地测试非常复杂的验证

答案 3 :(得分:1)

对于使用Rails 3.2.1及更高版本的用户,我更喜欢使用added?方法:

assert record.errors.added? :name, :blank

我使用的测试助手看起来像这样:

def assert_invalid(record, options)
  assert_predicate record, :invalid?

  options.each do |attribute, message|
    assert record.errors.added?(attribute, message), "Expected #{attribute} to have the following error: #{message}"
  end
end

这允许我编写这样的测试:

test "should be invalid without a name" do
  user = User.new(name: '')

  assert_invalid user, name: :blank
end

答案 4 :(得分:0)

您可以尝试rspec-on-rails-matchers。为您提供如下语法:

@thing.should validates_presence_of(:name)

答案 5 :(得分:0)

在带有MiniTest的更新版本的Rails(v5)中

test "create thing without name" do
    thing = Thing.new :param1 => "Something", :param2 => 123
    assert thing.invalid?
    assert thing.errors.added? :name, :blank
end

https://devdocs.io/rails~5.2/activemodel/errors