Hanami has builtin facilities for routing unit tests.

Path Generation

We can assert the generated routes, to do so, we’re gonna create a spec file for the purpose. Web.routes is the class that holds all the routes for the application named Web.

It exposes a method to generate a path, which takes the name of a route as a symbol. Here’s how to test it.

  1. # spec/web/routes_spec.rb
  2. RSpec.describe Web.routes do
  3. it 'generates "/"' do
  4. actual = described_class.path(:root)
  5. expect(actual).to eq('/')
  6. end
  7. it 'generates "/books/23"' do
  8. actual = described_class.path(:book, id: 23)
  9. expect(actual).to eq('/books/23')
  10. end
  11. end

Route Recognition

We can also do the opposite: starting from a fake Rack env, we can assert that the recognized route is correct.

  1. # spec/web/routes_spec.rb
  2. RSpec.describe Web.routes do
  3. # ...
  4. it 'recognizes "GET /"' do
  5. env = Rack::MockRequest.env_for('/')
  6. route = described_class.recognize(env)
  7. expect(route.routable?).to be(true)
  8. expect(route.path).to eq('/')
  9. expect(route.verb).to eq('GET')
  10. expect(route.params).to eq({})
  11. end
  12. it 'recognizes "PATCH /books/23"' do
  13. env = Rack::MockRequest.env_for('/books/23', method: 'PATCH')
  14. route = described_class.recognize(env)
  15. expect(route.routable?).to be(true)
  16. expect(route.path).to eq('/books/23')
  17. expect(route.verb).to eq('PATCH')
  18. expect(route.params).to eq(id: '23')
  19. end
  20. it 'does not recognize unknown route' do
  21. env = Rack::MockRequest.env_for('/foo')
  22. route = subject.recognize(env)
  23. expect(route.routable?).to be(false)
  24. end
  25. end

When we use .recognize, the router returns a recognized route, which is an object designed only for testing purposes. It carries on all the important information about the route that we have hit.