Earlier quoted context omitted.
> The "os.listdir()" example in this blog is a pretty common case, using mocks to test code that works with filesystems, where you don't need or want to get involved with actually creating filesystems which may be a complex and expensive process, especially if the test suite runs concurrent processes. Alternative: have an abstract base class that describes a file system API. Have one implementation that builds on top…
Sure but then I have to write my real library code using an abstraction, making my code more difficult to read and maintain; a dependency injection system is then necessary in order to have the correct concrete implementations set up at runtime. In this sense, mocks are solving the problem of having code that is full of dependency-injected AbstractFooBarFileSystemWithExtraPickles style of code, which is considered to…
Or easier - as the abstraction can simplify the interface, localize the logic for directory work, make it easier to port, and so on. That's the reason why most of us use "requests" and not urllib, too, for example, or Yoda and not Java's legacy time mess.
>a dependency injection system is then necessary in order to have the correct concrete implementations set up at runtime.
You can write alterative implementations (whether with base class, interface, traits, or what have you) and use them for production code and for testing without any dependency injection.
>Those of us using Python are using it because it is an interpreted, dynamic scripting language.
The abstractions mentioned come from Smalltalk, which arguably is the same or even more dynamic than Python. Having a class/interface/protocol/trait and a test implementation is by no means a static typing/Java thing, or counter to a dynamic language, as implied here...