For example, with-redefs. This allows you to replace a given function anywhere in the whole codebase with any lambda. This rebinding only lasts inside the scope of the s-expression. When I realized that, I realized everything I knew about DI and interfaces were just hacks of incredible complexity to get around a poor language that wasn't built to allow unit testing. I now think it's impossible to have both unit testing and a good design in Java/C#. Neither were made to be easy to unit test, it wasn't even a concept when Java was made.
In C#'s defense, there is a way to mock a static function by replacing it using the Mocks library. To MS's shame, that library requires the 13k edition of Visual Studio. When I realized that, I realized I want to leave C# for good. I'm not interested anymore in a language that resists testing so much I have to choose between an easy to understand design and unit tests.
It's a common misconception that interfaces are the only way to do polymorphism, because that's usually the only way in Java.