I'd like to thoroughly test a Rails application authorization setup (Pundit) with RSpec.
The Pundit docs and other respectful sources suggest writing unit tests for Pundit policy classes. Are those tests testing behavior (good) or implementation details (bad)?
If we were actually testing behavior, shouldn't our tests still pass if we eventually switched from Pundit to another authorization gem or rolled our own authorization?
Suppose a call to the
authorize
method is accidentally removed from a controller action, leaving it open for public access. Pundit policy tests will keep passing. If we have no other tests covering this, our test suite may be all green while our app has a serious security vulnerability. How can we avoid this? Maybe write unit tests for Pundit controller classes, separate unit tests for controllers and mock theauthorize
method in the controller tests to ensure they are called?
Edit: On second thought, I had a lapse of judgment regarding the difference between implementation details and the public API for a class. Calling specific public methods, passing specific arguments and expecting specific return values is a requirement to unit-test (and to use) any class. Please disregard item 3 as my original argument is invalid.
- Instead of testing Pundit policy classes, we could write controller or request specs that login with different user roles, call the controller actions and assert whether access was granted or denied. In this approach, the tests would keep passing even if we switched to another authorization gem. Also, they would fail if the
authorize
method is not called. However, these would be integration tests and should be slower that unit testing Pundit policy classes. Could that be a better way to test the authorization setup?
Thanks in advance.