Live data from Hacker News

Paving the on-ramp to Java

openjdk.org

131–140 of 156 posts

Re: Paving the on-ramp to Java

#131
post #126

Earlier quoted context omitted.

But even here you’re testing the same code twice. One directly with the tests for the class the static methods live in and once accidentally when you test the class that includes the util class as a dependency. This situation can be fixed by replacing the static methods with Functions.

> But even here you’re testing the same code twice So what? How is that a problem?

Because you have to address the separate permutations and concerns of multiple stack levels versus just declaring what you want the result to be from those additional stack levels. In essence, your "unit" test is a lie because your testing other units accidentally. I see a similar problems a lot with classes that have a small number of public methods which delegate to a larger stack of internal private calls. Unit tests are about testing the unit explicitly and forcing/contriving results of dependencies which you shouldn't be concerned with because those dependencies have been explicitly tested elsewhere. When these situations arise what you have are in memory integration tests, not unit tests.

As an example, suppose I have a static method that takes in an object and returns a result based on the state of that object. Now I have conditional logic in the unit under test that has a dependency on the result of that static method. In my unit test, I don't want to go to the trouble of creating the state of the object to force the delegate call to return a certain result that determines the execution flow, I want to just force that call to return the result I need.

Re: Paving the on-ramp to Java

#132
post #126

Earlier quoted context omitted.

> But even here you’re testing the same code twice So what? How is that a problem?

Because you have to address the separate permutations and concerns of multiple stack levels versus just declaring what you want the result to be from those additional stack levels. In essence, your "unit" test is a lie because your testing other units accidentally. I see a similar problems a lot with classes that have a small number of public methods which delegate to a larger stack of internal private calls. Unit te…

This is an extremely bad habit, people over use it to make testing easier by mocking all over the place. They end up writing tests that are coupled to the implementation, and any small change breaks them. Please go through the trouble to create the state of your object that you want to test, don't just mock other dependencies, which dependencies your method uses or how it does it's job is no concern of the test at all.

Re: Paving the on-ramp to Java

#133
post #132

Earlier quoted context omitted.

Because you have to address the separate permutations and concerns of multiple stack levels versus just declaring what you want the result to be from those additional stack levels. In essence, your "unit" test is a lie because your testing other units accidentally. I see a similar problems a lot with classes that have a small number of public methods which delegate to a larger stack of internal private calls. Unit te…

This is an extremely bad habit, people over use it to make testing easier by mocking all over the place. They end up writing tests that are coupled to the implementation, and any small change breaks them. Please go through the trouble to create the state of your object that you want to test, don't just mock other dependencies, which dependencies your method uses or how it does it's job is no concern of the test at al…

I agree, mocks should not be used and if you remove mock dependencies it usually exposes glaring problems in the code organization and design because the tests become overly complex. The dependencies should be coded to an interface so that you can inject whatever implementation you want.

Re: Paving the on-ramp to Java

#134
post #128
post #93

Earlier quoted context omitted.

Java is deliberately nudging you not to do things like that. It would rather you create a class with fields a and b -- which has its own verbosity, though they've improved it. I find that I use structures like that primarily when interfacing with other loosely-typed languages, like Javascript, which do encourage you to create structures on the fly like that. Impedance mismatch is always a pain, no matter where it occ…

Unit tests very frequently need Map declarations like that.

Unit tests are exactly one of those situations I had in mind. Unit tests are always kind of painful that way: you need to construct things by hand, using interfaces that were designed for automated use.

The same fact is what makes unit tests so brittle. Ideally, you do as little of that as possible: you less fake stuff you make, the more robust the test will be.

There are days you can't, and that sucks. But the language is giving you a nudge in the direction of how to do that, by making it easier to construct actual POJOs than unstructured intermediate data.

Re: Paving the on-ramp to Java

#135
post #129

Earlier quoted context omitted.

I wrote a lot of Java in the 2000's and the early 2010's. The verbosity of the language was always my #1 complaint. The amount of stuff I had to type vs the productivity of those lines was always out of whack. Maybe it's better now?

Requiring fewer lines for Hello World doesn't really change that though.

Alas, the language is incredibly verbose in and of itself and the plethora of examples continue to be incredibly verbose. From _Java in a Nutshell_ to the latest documentation, the examples all tend to be of the form:

UnbelievablyLongClassName unbelievablyLongClassName = new UnbelievablyLongClassName(parameterName, anotherParameterName);

Given that nearly all existing code follows this pattern (yes, there is var which is only useful in some cases as opposed to C++'s auto keyword) Java has become hopelessly convoluted.

Before I get downvoted, you should keep on mind that I was an early adopter (1996) of "Java as a sane C++" and have been stunned by the verbosity of "modern" Java applications. Unless the standard libraries change (and the effect of that would be staggering) and the open source libraries all change, and every existing application code changed to use reasonable names, Java will always be overly verbose.

Re: Paving the on-ramp to Java

#136
post #135
post #129

Earlier quoted context omitted.

Requiring fewer lines for Hello World doesn't really change that though.

Alas, the language is incredibly verbose in and of itself and the plethora of examples continue to be incredibly verbose. From _Java in a Nutshell_ to the latest documentation, the examples all tend to be of the form: UnbelievablyLongClassName unbelievablyLongClassName = new UnbelievablyLongClassName(parameterName, anotherParameterName); Given that nearly all existing code follows this pattern (yes, there is var whic…

> UnbelievablyLongClassName unbelievablyLongClassName = new UnbelievablyLongClassName(parameterName, anotherParameterName);

That's verbose, but how is it convoluted? It seems extremely plain and simple and linear to me? A local variable is set to a new instance of a class with a couple of parameters. What do you see as being convoluted here?

Re: Paving the on-ramp to Java

#137
post #126

Earlier quoted context omitted.

> But even here you’re testing the same code twice So what? How is that a problem?

Because you have to address the separate permutations and concerns of multiple stack levels versus just declaring what you want the result to be from those additional stack levels. In essence, your "unit" test is a lie because your testing other units accidentally. I see a similar problems a lot with classes that have a small number of public methods which delegate to a larger stack of internal private calls. Unit te…

> I don't want to go to the trouble of creating the state of the object to force the delegate call to return a certain result that determines the execution flow, I want to just force that call to return the result I need.

It certainly sounds like your stateful object is too complex. Simplify your state.

Re: Paving the on-ramp to Java

#138
post #114
post #59

Earlier quoted context omitted.

I always find it funny when people bring up Kotlin in the context of Java's evolution. It's not one of Java's main competitors, and while Java has borrowed many features from other languages [1], to date it has not adopted a single feature from Kotlin [2]. In fact, almost at every turn -- from data classes, through async/await, to string interpolation (JEP 430) -- Java has opted for a different approach. Is Kotlin th…

> Is Kotlin the only other language they know? On the JVM: I'd say yes. Scala, Groovy, Jython, JRuby, and what not came and went. I'd say Clojure is the third, and it take a nice place in the design space. But Kotlin to me is so close to Java that it is basically Java 2.0: the Java that Java cannot be due to intended organizational slowness. > Python is one of Java's main competitors, and when it comes to teaching a…

[deleted]

Re: Paving the on-ramp to Java

#139
post #132

Earlier quoted context omitted.

Because you have to address the separate permutations and concerns of multiple stack levels versus just declaring what you want the result to be from those additional stack levels. In essence, your "unit" test is a lie because your testing other units accidentally. I see a similar problems a lot with classes that have a small number of public methods which delegate to a larger stack of internal private calls. Unit te…

This is an extremely bad habit, people over use it to make testing easier by mocking all over the place. They end up writing tests that are coupled to the implementation, and any small change breaks them. Please go through the trouble to create the state of your object that you want to test, don't just mock other dependencies, which dependencies your method uses or how it does it's job is no concern of the test at al…

It's a good habit. The dependencies your method calls are externally facing, the same as it's API is.

Your method should follow a well rested interface for any touches that are outside of it:

* The input

* The return

* The side effects

You should be able to test that you've fixed a bug where you're calling a dependency 100 times instead of 1 time

Re: Paving the on-ramp to Java

#140

I am amused by this: > Worse, the early exposure to static methods will turn out to be a bad habit that must be later unlearned. I have been using Java since 1.0 and it is my default language. I am writing Java code today. I write functions using ‘static’ all the time. I prefer that a function be static. It shows that it does not depend on state of the enclosing object. Using ‘static’ on methods is not a bad habit. H…

It's worth keeping in mind that the primary audience that the article discusses is not folks at your skill level. By far one of the most common errors I see as a CS instructor is aggressive over-reliance on global state. Not global methods, but state. However, usually what causes the student to reach for global state is the fact that it can be accessed from a static method like main; In lieu of figuring out how to st…

I agree that this is a good way to simplify Java. I just don’t want newbie Java programmers told that static methods are bad because that is our only way to express pure functions and we need them to learn to default to immutable data and minimizing stateful objects.
Post reply on HN