Is using dependency injection (DI) essential for unit testing? 

I can't think of another alternative for isolating code so it can be tested. Also, all the examples I have ever seen use this pattern. Is that because it is the only viable option or are there other alternatives?

DI makes unit testing much easier. But you can still write unit tests without DI. Lots of unit tests have been written already before DI became widespread. (Of course, some of these used techniques identical or very similar to DI without knowing it has a fancy name :-)

I myself have used e.g. interfaces and factories a lot before learning about DI. The actual factory class name may have been read from a config file, or passed to the SUT as an argument.

Another approach is using singletons (or globally accessible data in general). Yes, I know it is not recommended by many (including myself) in general. Still it may be viable in specific situations, especially if the singleton contains static configuration data which is not test case specific, but differs between production and test environment. Of course it has its known problems, so DI is superior if you can use it. But often (e.g. in legacy systems) you can't.

Talking of which, Working Effectively With Legacy Code describes a lot of tricks to get legacy code covered by tests. Many of these are not nice, and aren't meant as a long term solution. But they allow you to create the first valuable unit tests to an otherwise untestable system... which enables you to start refactoring, and eventually (among others) introduce DI.
