Rails Testing Antipatterns: Controllers

This is the third post in the series about antipatterns in testing Rails applications. See part 1 for thoughts on fixtures and factories, and part 2 on models.

Imported from Disqus

Guest • 7 years ago

I like the idea of testing controllers in isolation, but before_filters, pagination libraries, and decorators always lead to epic mocking & stubbing for me.

My before filters check for login, admin, and to set the time-zone.
That requires me to stub out several of the user methods.
Pagination requires me to stub out things like current_page and Kaminari

How would you deal with these?

Marko Anastasov Mod Guest7 years ago

With before filters, you can DRY the spec up with shared contexts and examples. For example, if your index action requires user to be logged in, in your spec file you can verify that with

it_behaves_like "a member action that requires authenticated user", :index

and then include the shared context of user being logged in for all examples, not having to handle that further.

More domain specific before filters could also be moved to modules and tested with “dummy” controllers. Again in other cases you only need to verify that the controller under test includes the module in question.

Repetition in stubbing eg for .page can be avoided by having the stub as “early” in the spec as possible; sharing it across all examples that are not the one testing for the pagination, to avoid repetition.


Gabriel Lidenor5 years ago • edited

Well, you should use:

expect_any_instance_of(:User).to receive(:save).and_return(true)
expect_any_instance_of(PostSignUp).to receive(:run)

any_instance.stub is now deprecated