A unit in a real-world software system interfaces with many other units, internal and external. To have focused, isolated tests, we must somehow manage these interactions with other units. There are a few options. One is to simply use the other unit, as in the normal operation of the software in production. This option has the advantage that we don't do anything different in our tests, as compared to real-world usage of the software. However, this approach has two drawbacks. First, it undermines our goal of isolated unit testing by tying the tests for one unit with the exercise of code in another unit. Second, it is often not practical to load and set up the other unit in our tests due to a complex setup, external dependencies, and increased runtime of the test.
A common approach to dealing with the problem of external interfaces in testing is to use a mock in place of the other unit. Given Ruby's dynamic nature, it is quite easy to implement such a feature by using Module#define_method...