Live data from Hacker News

Stepping down as Mockito maintainer after ten years

github.com

191–200 of 220 posts

Re: Stepping down as Mockito maintainer after ten years

#191

Earlier 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…

The second way is usually referring to as "fakes", which are not a type of mocks but a (better) alternative to mocks.

In reflection heavy environments and with injection and reflection heavy frameworks the distinction is a bit more obvious and relevant (.Net, Java). In some cases the mock configuration blossoms to essentially parallel implementations, leading to the brittleness discussed earlier in the thread.

Technically creating a shim or stub object is mocking, but “faking” isn’t using a mocking framework to track incoming calls or internal behaviours. Done properly, IMO, you’re using inheritance and the opportunity through the TDD process to polish & refine the inheritance story and internal interface of key subsystems. Much like TDD helps design interfaces by giving you earlier external interface consumers, you also get early inheritors if you are, say, creating test services with fixed output.

In ideal implementations those stub or “fake” services answer the “given…” part of user stories leaving minimalistic focused tests. Delivering hardcoded dictionaries of test data built with appropriate helpers is minimal and easy to keep up to date, without undue extra work, and doing that kind of stub work often identifies early re-use needs/benefits in the code-base. The exact features needed to evolve the system as unexpected change requests roll in are there already, as QA/end-users are the systems second rodeo, not first.

The mocking antipatterns cluster around ORM misuse and tend to leak implementation details (leading to those brittle tests), and is often co-morbid with anemic domains and other cargo cult cruft. Needing intense mocking utility and frameworks on a system you own is a smell.

For corner cases and exhaustiveness I prefer to be able to do meaningful integration tests in memory as far as possible too (in conjunction with more comprehensive tests). Faster feedback means faster work.

Re: Stepping down as Mockito maintainer after ten years

#192
post #187
post #176

Earlier quoted context omitted.

I’m sorry, but null restricted types, string templates, basic json support, and fixing the broken exception system isn’t “fat”. They’re the basics of a functioning language.

Handling JSON as a basics for language? Really? null restricted type will come with valhalla, string templates had a try, but people complained and they withdrawn them after 2 preview iterations. Not sure what issue people had with them and what issues maintainers noticed. What do you mean by broken exception system? Java is not a small language that you can throw features around, they have to take into consideration…

> Handling JSON as a basics for language?

Yes, even Mark Reinhold admitted that in the last "Ask the Architects" interview.

>null restricted type will come with valhalla

Will they? It's been 10+ years of Valhalla. Why is a compiler construct even behind project Valhalla? Kotlin has showed you don't need it to do them.

> string templates had a try

Yes they were over engineered and they failed to deliver a basic feature.

> Java is not a small language that you can throw features around, they have to take into consideration final goal of it and decades of development.

Yes I agree, but it shouldn't take YEARS to ship anything. 11 years for a JSON api?! Come on.

Re: Stepping down as Mockito maintainer after ten years

#193
post #66
post #31

> To me, it felt like the feature was presented as a done deal because of security. Not security, but integrity, although security (which is the #1 concern of companies relying on a platform responsible for trillions of dollars) is certainly one of the primary motivations for integrity (others being performance, backward compatibility or "evolvability", and correctness). Integrity is the ability of code to locally de…

What am I missing that makes this change a massive headache if just setting a flag gets the old behavior?

The auto-attach flag isn’t a huge deal, since it’s a one-liner that can be statically documented and the fix works in all cases. The bigger issue is the JDK / runtime team’s stance that libraries should not be able to dynamically attach agents, and that the auto-attach flag might be removed in the future. You can still enable mockito’s agent with the —javaagent flag, but you have to provide the path to the mockito jar, and getting that path right is highly build-system-dependent and not something the mockito team can document in a way that minimizes the entry threshold for newcomers.

Re: Stepping down as Mockito maintainer after ten years

#194
post #50

Earlier quoted context omitted.

No, some other library classes accept only their own, not my adapter. Not mentioning of course needless copy-pasting dosens of members in the adapter. And it must be in prod code, not tests, even though it's documentation would say "Adapter for X, exists only for tests, to be able to mock X".

You wrap whole 3rd party dependency in an adapter.

The second argument still holds -- all those wrappers will exist in prod only for tests.

Moreover, that wrapper library is now a pretty large piece of code, and we'd want to maintain and test as well. But cannot without hacks.

Re: Stepping down as Mockito maintainer after ten years

#195
post #158

Earlier quoted context omitted.

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…

The point is that you probably don't care that much how exactly the dependency is called, as long as it is called in such a way that it does the action you want and returns the results you're interested in. The test shouldn't be "which methods of the dependency does this function call?" but rather "does this function produce the right results, assuming the dependency works as expected?". This is most obvious with com…

In the SQL example, unless you actually use an SQL service as a fake, you cannot really quite get the fake do the right thing either. At which point, it's no longer a mock/fake test but an integration/DB test. Network servers are another such class and for most parts can be either mocked or faked using interface methods.

I would argue that (barring SQL), if there are too many ways to skin a cat, it is a design smell. Interfaces are contracts. Even for SQL, I almost end up using a repository method (findByXxx flavors) so it is very narrow in scope.

Re: Stepping down as Mockito maintainer after ten years

#196

Earlier quoted context omitted.

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.

The point is to test against a model of the dependency, not just the expected behavour of the code under test. If you just write a mock that exactly corresponds to the test that you're running, you're not testing the interface with the underlying system, you're just running the (probably already perfectly understandable) unit through a rote set of steps, and that's both harder to maintain and less useful than testing…

But mocks are a model of the dependency. I don't quite see how a fake is a better model than a mock.

In any case, I agree testing close to a real system, with actual dependencies where possible is better. But that's not done with a fake.

Re: Stepping down as Mockito maintainer after ten years

#197

Earlier quoted context omitted.

The point is to test against a model of the dependency, not just the expected behavour of the code under test. If you just write a mock that exactly corresponds to the test that you're running, you're not testing the interface with the underlying system, you're just running the (probably already perfectly understandable) unit through a rote set of steps, and that's both harder to maintain and less useful than testing…

But mocks are a model of the dependency. I don't quite see how a fake is a better model than a mock. In any case, I agree testing close to a real system, with actual dependencies where possible is better. But that's not done with a fake.

The kind of mocks the OP is arguing against are not really a model of the dependency, they're just a model of a particular execution sequence in the test, because the mock is just following a script. Nothing in it ensures that the sequence is even consistent with any given understanding of how the dependency works, and it will almost certainly need updating when the code under test is refactored.

Re: Stepping down as Mockito maintainer after ten years

#198
post #66

Earlier quoted context omitted.

What am I missing that makes this change a massive headache if just setting a flag gets the old behavior?

The auto-attach flag isn’t a huge deal, since it’s a one-liner that can be statically documented and the fix works in all cases. The bigger issue is the JDK / runtime team’s stance that libraries should not be able to dynamically attach agents, and that the auto-attach flag might be removed in the future. You can still enable mockito’s agent with the —javaagent flag, but you have to provide the path to the mockito ja…

[deleted]

Re: Stepping down as Mockito maintainer after ten years

#199

Earlier quoted context omitted.

For the same reason you isolate variables in a scientific experiment; to ensure you're controlling the test that you're running, and not accidentally testing something else. To easily simulate failure cases, a range of possible inputs, bad data etc. To make the testing process faster when you have hundreds or thousands of tests, running on multiple builds simultaneously across an organisation. Off the top of my head…

I don’t think it’s worth doing that, and comparing it to scientific experiments doesn’t really apply. You can do all that without mocks as well. Making the tests run faster at the expense of better tests seems counterproductive. Now you should think of reasons why you should not isolate.

> I don’t think it’s worth doing that

OK; it's your choice to do what you think is right.

> and comparing it to scientific experiments doesn’t really apply.

Why not? I think it's a fairly apt comparison; you have a theory ("this piece of code does the following things"), and write tests to prove it.

> You can do all that without mocks as well.

OK, but mocks make it easier and cleaner - so why wouldn't I do that?

> Making the tests run faster at the expense of better tests seems counterproductive.

Smaller, more focused, cleaner tests are better in my opinion; speed is a beneficial side effect.

> Now you should think of reasons why you should not isolate.

Why? That's your argument - it's not on me to prove it for you. If you can give me some good reason why mocking out the interfaces you are not testing is a bad idea, and some better alternative, then we can have a discussion about it.

Re: Stepping down as Mockito maintainer after ten years

#200

Earlier quoted context omitted.

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…

> Using mocks properly is a sign of a well-factored codebase. Well-factored codebase doesn’t need mocks.

That's not a counter-argument. Why don't you need to mock out the interfaces that you're not testing?
Post reply on HN