I still have a bad understanding of this, I want to hear how to do better and why it is better than other options.
95% of visitors to this site do not know the word "mock", of the remaining 4/5 are lazy or do not have time to use moki in daily development.
As for unit testing, it is carried out in isolation and component by component. We have the functionality to delete the file, we test it separately; we have the functionality of getting a list of files for duplication, we also test it separately; together they are not tested as part of unit tests.
If we go to a higher level, then it is not necessary to apply moki at all. We take a virtual file system (I personally use the mikey179 / vfsStream package, but it’s not very convenient, I haven’t seen it conveniently), we deploy it there, we want to check that everything has been cleaned up after the execution of the code. Long, expensive, like Lebedev. I am testing one class autoloader in this way to find files.
If none of the options fit: decoupl'im a class, create a setOwner(OwnerInterface $owner) method setOwner(OwnerInterface $owner) , prokakyvaem mok, mok returns mocks of class Image with an empty method clearCache() , which should be called exactly once on each moke (Codeception Stub is surely can, other mock-libraries for sure too).
As for the architecture: it must be finished. The image should not manage its cache, the owner is unlikely to manage the images in order to edit their cache, the third-party class has nothing to do with it. Some ImageManager should receive images associated with the user, get their paths, and feed CacheManager as keys that need to drop the cache. The owner himself is not involved here. CacheManager is not aware of the mechanism for obtaining keys, ImageManager does not know where its result will go, re-usability is increasing.
and embed it in the mock Class object
The test object is best not to mok. We need mock only to replace the dependencies and thus isolate the test from the influence of external factors.
create methods for Class in which to call the owner methods, and override them in the mock object
Know This will significantly increase the dependencies in the system, at the same time the class for some reason will begin to duplicate the owner functional, although it has no relation to this functionality.
One last thing: PHP is not yet mature enough for serious languages in terms of architecture, but yii is a fractal of bad architecture. The second version, of course, corrected many shortcomings, but still there is full of hell and death, and the writing is almost impossible to reuse, because for some reason everything must lie in one namespace app and that's it. The result will certainly be exactly the same name conflict that interfered in the first version. Yii does not obey the logic and will not, yii is written to solve specific problems that arise here, without regard to what may be needed. This has a good effect on the rapid development of simple applications, but as the complexity increases, the hell degree grows exponentially.