No release in over a year
Extra matchers to test model validation
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies
 Project Readme

RspecModelValidations

Extra matchers to improve testing of model validation

Testing model validation can be a bit clunky:

  • model.valid? test the entire model so it can lead to errors
  • specific error on attribute can be test with model.added? or errors[:attribute] but options or message must be provided
  • attribute setting and validation trigger must be call
  • as validation are test through "raw code" failure message can be hard to understand

rspec_model_validations make testing smoother by adding matchers to focus test on specific attribute / validation.

  # model
  validates :attribute, numericality: true

  # spec
  expect(model).to invalidate(:attribute).with(:blank, :not_a_number).on nil

  # equivalent to
  model.attribute = nil
  model.validate
  expect(model.errors).to be_added :attribute, :blank
  expect(model.errors).to be_added :attribute, :not_a_number, value: nil

Requirements

  • ~> 1.0: rails ~> 7.0

Note: it should be able to run with older version of rails but behaviour is not garanted.

Installation

  1. Add this gem to your application in :test env
  gem 'rspec_model_validations', '~> 1.0', require: false, group: :test
  1. Setup spec/rails_helper.rb file to access matchers
  # Add additional requires below this line. Rails is not loaded until this point!
  require 'rspec_model_validations'

  # ...

  RSpec.configure do |config|
    config.include RspecModelValidations::Matchers
  end

Usage

Test validation errors

invalidate :attribute test errors on a specific attribute. It run validation and test that the targeted attribute have at least one error.

  model.attribute = nil
  expect(model).to invalidate :attribute

  # equivalent to
  model.attribute = nil
  model.validate
  expect(model.errors[:attribute]).to be_present

Options:

  • with specify which errors type must be present. It accept single or multiple symbols.
  model.attribute = nil
  expect(model).to invalidate(:attribute).with :blank, :not_a_number

  # equivalent to
  model.attribute = nil
  model.validate
  expect(model.errors.group_by_attribute(:attribute).map(&:type)).to include(:blank, :not_a_number)
  • on set the attribute value
  expect(model).to invalidate(:attribute).on nil

  # equivalent to
  model.attribute = nil
  model.validate
  expect(model.errors[:attribute]).to be_present

Test successfull validation

validate :attribute test a specific attribute validity. It run validation and then test that none errors are related to the given attribute.

  model.attribute = 9
  expect(model).to validate :attribute

  # equivalent to
  model.attribute = 9
  model.validate
  expect(model.errors[:attribute]).to be_empty

Options:

  • on see invalidate on option