Stepping down as Mockito maintainer after ten years
151–160 of 220 posts
Re: Stepping down as Mockito maintainer after ten years
#152Earlier quoted context omitted.
It didn't. They're examples of features that have driven Kotlin's growth. Thing's Java developers have been begging for. I'm using them as examples of why Java developers are starting to choose Kotlin. I'm a pretty die hard Java fan, I've built my career on it, and know way too much about the ecosystem. But, I've been writing F#, C#, Kotlin, and some other languages in my free time to see where I want to move to. I’m…
Oh I see, thank you for explaining. PS: personally I really like Swift, I would suggest giving it a try for fun
I don’t think it’s for me though. It’s very Apple centric and I’m a Windows gamer and PowerShell user at heart.
Re: Stepping down as Mockito maintainer after ten years
#153Earlier quoted context omitted.
I'm not sure I understand. "The solution is to have dummy versions of services and interfaces that have minimal correct behavior". That's mocks in a nutshell. What other way would you use mocks?
There are different kinds of mocks. Check function XYZ is called, return abc when XYZ is called etc are the bad kind that people were bit badly by. The good kind are a minimally correct fake implementation that doesn't really need any mocking library to build. Tests should not be brittle and rigidly restate the order of function calls and expected responses. That's a whole lot of ceremony that doesn't really add conf…
Why is a minimally correct fake any better than a mock in this context?
Mocks are not really about order of calls unless you are talking about different return values on different invocations. A fake simply moves the cheese to setting up data correctly, as your tests and logic change.
Not a huge difference either way.
Re: Stepping down as Mockito maintainer after ten years
#154Earlier quoted context omitted.
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.
Well, no - you don't. What you're describing is a very limited subset of testing, which presumably is fine for the projects you work on, but that experience does not generalise well. Integration testing is of course useful, but generally one would want to create unit tests for every part of the code, and by definition it's not a unit test if hits multiple parts of the code simultaneously. Apart from that, databases a…
The common pitfall with this style of testing is that you end up testing implementation details and couple your tests to your code and not the interfaces at the boundaries of your code.
I prefer the boundary between unit and integration tests to be the process itself. Meaning, if I have a dependency outside the main process (eg database, HTTP API etc) then it warrants an integration test where i mock this dependency somehow. Otherwise, unit tests test the interfaces with as much coverage of actual code execution as possible. In unit tests, out of process dependencies are swapped with a fake implementation like an in-memory store instead of a full of fledged one that covers only part of interface that i use. This results in much more robust tests that I can rely on during refactoring as opposed to “every method or function is a unit, so unit tests should test these individual methods”.
Re: Stepping down as Mockito maintainer after ten years
#155Earlier quoted context omitted.
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.
What's specifically bad about Mockito here? Poor defaults for mocks?
Re: Stepping down as Mockito maintainer after ten years
#156Earlier quoted context omitted.
I liked Groovy, but Kotlin was the better successor. Scala was beyond ridiculous as far as learning curve--crazy language. I always thought Java sucked and I spent far too much time working with Java (because money) and having to deal with framework on top of framework as well as all those idiotic design patterns that seemed so important only for me to realize years later that it was all basically a waste because OOP…
I still miss dependency injection in Python
Re: Stepping down as Mockito maintainer after ten years
#157Hey, fwiw, thank you for all of your hard work! Mockito and Powermock helped me be a big hero at one company I worked for 2011-2014. Before I arrived as a tech lead there, they had ZERO tests. The QA cycle was weeks, even months long. I instituted a whole new regime of unit and intergration testing for all the applications I was responsible for. Within one release cycle, the bug counts fell to nearly zero and the QA…
I (ironically enough) spent some time replacing usages of it in Kafka test code with Mockito because of this, IIRC there was only one situation where Mockito couldn't easily replace Powermock and I'm pretty sure it was mocking out a private static method, so the solution was to refactor the code under test so that you didn't need to mock a private static method to test it.
Re: Stepping down as Mockito maintainer after ten years
#158Earlier quoted context omitted.
Imagine you're testing a service to creates, queries and deletes users. A fake version of that service might just be a wrapper on a HashMap keyed by ID. It might have several fields like some personal info, a hashed password, an email address, whether you're verified and so on. Imagine one of your tests is if the user deletes their account. What pattern of calls should it make? You don't really care other than the re…
I am unsure I follow this. I'm generally mocking the things that are dependencies for the thing I'm really testing. If the dependencies are proper interfaces, I don't care if it's a fake or a mock, as long as the interface is called with the correct parameters. Precisely because I don't want to test the implementation details. The assumption (correctly so) is that the interface provides a contract I can rely on. In y…
This is most obvious with complex interfaces where there are multiple ways to call the dependency that do the same thing. For example if my dependency was an SQL library, I could call it with a string such as `SELECT name, id FROM ...`, or `SELECT id, name FROM ...`. For the dependency itself, these two strings are essentially equivalent. They'll return results in a different order, but as long as the calling code parses those results in the right order, it doesn't matter which option I go for, at least as far as my tests are concerned.
So if I write a test that checks that the dependency was carried with `SELECT name, id FROM ...`, and later I decide that the code looks cleaner the other way around, then my test will break, even though the code still works. This is a bad test - tests should only fail if there is a bug and the code is not working as expected.
In practice, you probably aren't mocking SQL calls directly, but a lot of complex dependencies have this feature where there are multiple ways to skin a cat, but you're only interested in whether the cat got skinned. I had this most recently using websockets in Node - there are different ways of checking, say, the state of the socket, and you don't want to write tests that depend on a specific method because you might later choose a different method that is completely equivalent, and you don't want your tests to start failing because of that.
Re: Stepping down as Mockito maintainer after ten years
#159Earlier quoted context omitted.
That’s the seductive power of mocking - you get a test up and running quickly. The benefit to the initial test writer is significant. The cost is the pain - sometimes nightmarish - for other contributors to the code base since tests depending on mocking are far more brittle. Someone changes code to check if the ResultSet is empty before further processing and a large number of your mock based tests break as the origi…
> Someone changes code to check if the ResultSet is empty before further processing and a large number of your mock based tests break as the original test author will only have mocked enough of the class to support the current implementation. So this change doesn't allow an empty result set, something that is no longer allowed by the new implementation but was allowed previously. Isn't that the sort of breaking chang…
If tests (authored by someone else) break, I now have to figure out whether the breakage is due to the fact that not enough behavior was mocked or whether I have inadvertently broken something. Maybe it’s actually important that code avoid using “isEmpty”? Or do I just mock the isEmpty call and hope for the best? What if the existing mocked behavior for size() is non-trivial?
Typically you’re not dealing with something as obvious.
Re: Stepping down as Mockito maintainer after ten years
#160Earlier quoted context omitted.
There are different kinds of mocks. Check function XYZ is called, return abc when XYZ is called etc are the bad kind that people were bit badly by. The good kind are a minimally correct fake implementation that doesn't really need any mocking library to build. Tests should not be brittle and rigidly restate the order of function calls and expected responses. That's a whole lot of ceremony that doesn't really add conf…
Why is check if XYZ is called with return value ABC bad, as long as XYZ is an interface method? Why is a minimally correct fake any better than a mock in this context? Mocks are not really about order of calls unless you are talking about different return values on different invocations. A fake simply moves the cheese to setting up data correctly, as your tests and logic change. Not a huge difference either way.
(And IMO this should only be done for heavyweight or difficult to precisely control components of the system where necessary to improve test runtime or expand the range of testable conditions. Always prefer testing as close to the real system as reasonably practical)