In the context of Rails, stubbing/mocking are invaluable in the effort to adhere to a reasonable-looking test pyramid.
Take Rails controller tests, for example.
Rails controllers:
- receive request body
- (ideally) delegate the heavy-lifting associated with processing request to other objects
- respond to the request
Unit testing controllers would then involve documenting through tests that the controller responds favourably to a variety of request bodies -- all one should care about are the requests, and the responses of controller actions and the return value of the the objects that do the heavy lifting in step 2.
, which one can easily achieve by mocking the objects in step 2.
or by stubbing the response of some method calls. (As a prerequisite, I would ensure that the objects that do the heavy-lifting have unit tests of their own before mocking them away in the controller tests.)
Depending on your application, you may also decide to not write controller tests with mocks and instead write integration tests to also test the objects. This is sometimes the ideal approach, especially when the worker objects are themselves pretty light-weight. At the end of the day, I would try to ensure that I don't invert the testing pyramid, although there are probably cases in which it is okay to do so.
In model/service object tests, personally, I also like to not interact with databases if the operation is expensive and redundant.
The advantage of mocking is obvious in integration tests, particularly in a microservices based architectures, where your application has to do is communicate over networks, and it isn't concerned with how other services process requests. Being able to stub the response of other services is very important.