TheProlog / prolog_minitest_matchers

Custom Minitest matcher(s) we've developed for our own use, and which others may find useful.
MIT License
0 stars 0 forks source link

Implement `assert_requires_dry_struct_attribute` and `must_require_dry_struct_attribute ` #5

Closed jdickey closed 8 years ago

jdickey commented 8 years ago

New Matcher Spec

A near-clone of what has gone before, particularly assert_requires_initialize_parameter and must_require_initialize_parameter.

Given a class under test similar to

class User < Dry::Types::Struct
  attribute :name, Types::Strict::String
  attribute :age, Types::Coercible::Int
end

then we want a single-assertion test that failing to specify a supposedly required attribute value when initialising actually would trigger an error:

describe 'must be initialised with attribute values for' do
  let(:params) { { name: 'Some User', age: 42 } }

  it ':age' do
    expect(User).must_require_initialize_parameter params, :age
  end

  it ':name' do
    expect(User).must_require_initialize_parameter params, :name
  end
end # describe 'must be initialised with attribute values for'

Without this custom matcher, one of the tests would look something like

describe 'must be initialised with attribute values for' do
  let(:params) { { name: 'Some User', age: 42 } }

  after do
    message = "[User.new] #{@param} is missing in Hash input"
    params.delete @param
    error = expect { User.new params }.must_raise Dry::Struct::Error
    expect(error.message).must_equal message
  end

  it ':age' do
    @param = :age
  end

  it ':name' do
    @param = :name
  end
end # describe 'must be initialised with attribute values for'

Lots more boilerplate; much less clarity on what is actually being tested and why.

jdickey commented 8 years ago

Commit 1c78e0b basically demonstrates how we should have (re)written the asserters after writing the second very similar one. The other thing to notice is that, contrary to previous standard practice, the InduceError and VerifyKeyInHash support methods aren't namespaced at all; we anticipate (eventually) moving them someplace more easily reusable.