Strong parameters are a way of white listing HTTP query parameters and moves the burden of whitelisting from the ActiveModel/ActiveRecord classes and into the controllers.My view is that this testing strategy is far too complex, and here I outline a simpler approach.
First, let's understand the API. It was a bit tricky for me at first, partly because the documentation is vague.
We can whitelist attributes via the permit method, and we can require them via the require method.
Regarding the handling of missing or unpermitted keys, here's what the docs say:
By default parameter keys that are not explicitly permitted will be logged in the development and test environment. In other environments these parameters will simply be filtered out and ignored.The unpermitted key behavior happens instantly. That is, if you require a parameter that's missing, you get an ActionController::ParameterMissing exception. If you permit some parameters, any unpermitted parameters will instantly be indicated via an ActionController::UnpermittedParameters exception or a log line, depending on your action_on_unpermitted_parameters setting.
Additionally, this behaviour can be changed by changing the config.action_controller.action_on_unpermitted_parameters property in your environment files. If set to :log the unpermitted attributes will be logged, if set to :raise an exception will be raised.
Note that this means you don't want to have a permit before a require if you're using the :raise option (which I strongly suggest you do, because that's confident coding), because the permit call would then raise an exception.
But what's this default behavior where keys that are not permitted are "filtered out and ignored"? This just means that the call to permit returns a hash in which the unpermitted keys are removed. The original params object is unaltered.
In any case, this brings us back to..
First off, recognize that it's easy to test that all the right parameters are permitted. We simply write a controller test using an update hash including all of the permitted parameters.
Now, to assert that any other params aren't permitted, we simply make a context in which we have a single unpermitted parameter, and assert that the unpermitted attribute isn't updated.
But now what about require? That's considerably more work to test, since you'd have to make nested contexts for every single required parameter. Therefore I advise simply not to use require at all. I'm not even sure why it was added. Feel free to tell me if you can think of a good reason.
This strategy is just radically simpler than the approach Robbie Clutton took.