Earlier quoted context omitted.
It’s taken years off of my life dealing with the test mess people have made with it.
Absolutely the worst. 1000 line test setups that shatter into pieces the instant you try to make the simplest change to a function. Makes refactoring an absolute nightmare.
Stepping down as Mockito maintainer after ten years
91–100 of 220 posts
Re: Stepping down as Mockito maintainer after ten years
#92Re: Stepping down as Mockito maintainer after ten years
#93Earlier quoted context omitted.
The whole mocks, fakes and the rest were always a terrible idea. Although people didn't realize it st the time, they were a band-aid to try to make poorly architected code testable. 90% of the time, needing to use a mock is one of the clearest code warning smells you have of there being an issue in the design your code. It took a while, but the industry seems to be finally (although slowly) coming to this realization…
How do you substitute for dependencies that you're not testing, or that you want to deliberately break?
Re: Stepping down as Mockito maintainer after ten years
#94This is a good opportunity to ditch mocking and use fakes with adapters. Not only mocks create brittle tests that often test only the framework itself, but they do so in an order of magnitude slower way. Also, F Kotlin and their approach of "we'll reinvent the wheel with slightly different syntax and call it a new thing". Good riddance I say, let them implement their mockk, or whatever it is called, with ridiculous "…
The whole mocks, fakes and the rest were always a terrible idea. Although people didn't realize it st the time, they were a band-aid to try to make poorly architected code testable. 90% of the time, needing to use a mock is one of the clearest code warning smells you have of there being an issue in the design your code. It took a while, but the industry seems to be finally (although slowly) coming to this realization…
Re: Stepping down as Mockito maintainer after ten years
#95Wow, there's a lot of anger in some of these posts. I've been using Mockito for about 4 years, all in Kotlin. I always found it to be "plenty good" for like 99% of the cases I needed it; and things more complicated or confusing or messy were usually my fault (poor separation of concerns, etc). I regularly found it quite helpful in both its spy() and mock() functionality. I never found it meaningfully more or less use…
Is it anger? The agent thing maybe. The other two points seem to boil down to: 1. Kotlin is a hack and 2. Rust is more fun. Pretty understandable why one would simply want to move on to greener pastures.
Here are some examples that have hit the graveyard: It's been 2 years since exception handling in switch was proposed [0], 3 years since null-restricted types were proposed [1], 4 years since string templates [2], 8 years since concise method bodies [3], and 11 years for JSON parsing [4].
[0] https://inside.java/2023/12/15/switch-case-effect/
[1] https://openjdk.org/jeps/8303099
[2] https://openjdk.org/jeps/430
Re: Stepping down as Mockito maintainer after ten years
#96My second project at Google basically killed mocking for me and I've basically never done it since. Two things happened. The first was that I worked on a rewrite of something (using GWT no less; it was more than a decade ago) and they decided to have a lot of test coverage and test requirements. That's fine but they way it was mandated and implemented, everybody just testing their service and DIed a bunch of mocks in…
“The solution is to have dummy versions of services and interfaces that have minimal correct behavior” If you aren’t doing this with mocks then you’re doing mocks wrong.
Going further, there’s the whole test containers movement of having a real version of your dependency present for your tests. Of course, in a microservices world, bringing up the whole network of dependencies is extremely complicated and likely not warranted.
Re: Stepping down as Mockito maintainer after ten years
#97Earlier quoted context omitted.
IMO Mockito is fine, the problem I’ve encountered is people taking the easy way out and trying to test something that needs a real integration test with a convoluted series of mocks.
I've found that most of the time that if you need to mock, you probably just need to do an integration test.
I’ve been on projects where mocking _literally made the project less reliable_ because people ended up “testing” against mocks that didn’t accurately reflect the behavior of the real APIs.
It left us with functionality that wasn’t actually tested and resulted in real bugs and regressions that shipped.
Mocking is one of these weird programmer pop-culture memetic viruses that spread in the early 2000s and achieved complete victory in the 2010s, like Agile and OOP, and now there are entire generations of devs who it’s not that they’re making a bad or a poorly argued choice, it’s that they literally don’t even know there are other ways of thinking about these problems because these ideas have sucked all the oxygen out of the room.
Re: Stepping down as Mockito maintainer after ten years
#98My second project at Google basically killed mocking for me and I've basically never done it since. Two things happened. The first was that I worked on a rewrite of something (using GWT no less; it was more than a decade ago) and they decided to have a lot of test coverage and test requirements. That's fine but they way it was mandated and implemented, everybody just testing their service and DIed a bunch of mocks in…
“The solution is to have dummy versions of services and interfaces that have minimal correct behavior” If you aren’t doing this with mocks then you’re doing mocks wrong.
That said, there is a massive difference between writing mocks and using a mocking library like Mockito — just like there is a difference between using dependency injection and building your application around a DI framework.
Re: Stepping down as Mockito maintainer after ten years
#99My second project at Google basically killed mocking for me and I've basically never done it since. Two things happened. The first was that I worked on a rewrite of something (using GWT no less; it was more than a decade ago) and they decided to have a lot of test coverage and test requirements. That's fine but they way it was mandated and implemented, everybody just testing their service and DIed a bunch of mocks in…
“The solution is to have dummy versions of services and interfaces that have minimal correct behavior” If you aren’t doing this with mocks then you’re doing mocks wrong.
For example, let's say you want to test that some handler is properly adding data to a cache. IMO the traditional mock approach that is supported by mocking libraries is to go take your RedisCache implementation and create a dummy that does nothing, then add assertions that say, the `set` method gets called with some set of arguments. You can add return values to the mock too, but I think this is mainly meant to be in service of just making the code run and not actually implementing anything.
Meanwhile, you could always make a minimal "test" implementation (I think these are sometimes called "fakes", traditionally, though I think this nomenclature is even more confusing) of your Cache interface that actually does behave like an in-memory cache, then your test could assert as to its contents. Doing this doesn't require a "mocking" library, and in this case, what you're making is not really a "mock" - it is, in fact, a full implementation of the interface, that you could use outside of tests (e.g. in a development server.) I think this can be a pretty good middle ground in some scenarios, especially since it plays along well with in-process tools like fake clocks/timers in languages like Go and JavaScript.
Despite the pitfalls, I mostly prefer to just use the actual implementations where possible, and for this I like testcontainers. Most webserver projects I write/work on naturally require a container runtime for development for other reasons, and testcontainers is glue that can use that existing container runtime setup (be it Docker or Podman) to pretty rapidly bootstrap test or dev service dependencies on-demand. With a little bit of manual effort, you can make it so that your normal test runner (e.g. `go test ./...`) can run tests normally, and automatically skip anything that requires a real service dependency in the event that there is no Docker socket available. (Though obviously, in a real setup, you'd also want a way to force the tests to be enabled, so that you can hopefully avoid an oopsie where CI isn't actually running your tests due to a regression.)
Re: Stepping down as Mockito maintainer after ten years
#100Earlier quoted context omitted.
How do you substitute for dependencies that you're not testing, or that you want to deliberately break?
90% of the time (or more): you don't. The real thing is perfectly fine in a test with the right setup. Fileio is fast, I just need a test file in a tempdir. databases are fast, I just need an easy way to settup my schema. Sometimes I need the isolation but normally I do not.
Even funnier, this was all hypothetical and yet taken as gospel. We hadn't even written the tests yet, so it was impossible to say whether they were slow or not. Nothing had been measured, no performance budget had been defined, no prototype of the supposedly slow tests had been written to demonstrate the point.
We ended up writing - no joke - less than 100 tests total, almost all of which hit the database, including some full integration tests, and the entire test suite finished in a few seconds.
I'm all for building in a way that respects performance as an engineering value, but we got lost somewhere along the way.