JUnit Test



  • Why?:

     

    public class TestJavaLibraries {
    /**
    * Verify the library code still caches intern'd strings
    */
    @Test
    public void testCachingInternedStrings() {
    String a = "Hello";
    String b = new StringBuilder("Hello").toString();
    assertFalse(a == b);
    assertTrue(a.intern() == b.intern());
    }

    /**
    * Verify the library code still caches immutable longs
    */
    @Test
    public void testCachingImmutableLongs() {
    for (long i=0; i<128; i++) {
    Long a = Long.valueOf(i);
    Long b = Long.valueOf(i);
    assertTrue(a == b);
    }
    }

    /**
    * Verify the library code still caches immutable shorts
    */
    @Test
    public void testCachingImmutableIntegers() {
    for (int i=0; i<128; i++) {
    Integer a = Integer.valueOf(i);
    Integer b = Integer.valueOf(i);
    assertTrue(a == b);
    }
    }

    /**
    * Verify the library code still caches immutable shorts
    */
    @Test
    public void testCachingImmutableShorts() {
    for (short i=0; i<128; i++) {
    Short a = Short.valueOf(i);
    Short b = Short.valueOf(i);
    assertTrue(a == b);
    }
    }
    }


  • But hey, you have unit tests! That counts for something in the PHB checklist.



  • Bizarre humour, I hope. Otherwise, I'd be afraid of what lurks within this code. Good luck



  • Why?  Because you must test everything! And then your codebase will be magical and shiny and all your code works!

    You obviously don't understand. Have some more Kool-Aid.



  • What, no tests that check if true is not false and that up is not down? Pfft.



  •  Except for the first test, the behavior is not guaranteed by the Java specification. So if the application relies on this behavior, it should be tested? (Although the application should not rely on the identity of small boxed values).

     For integers, I believe, it is actually possible to change the upper limit via VM options. Maybe you should try if it breaks something.



  • @derari said:

    Except for the first test, the behavior is not guaranteed by the Java specification.

    Wrong! All but the second is guaranteed.



  • @morbiuswilters said:

    @derari said:
    Except for the first test, the behavior is not guaranteed by the Java specification.

    Wrong! All but the second is guaranteed.

    The link you gave doesn't support your claim.

    The link says that boxing conversions always return the same object for small ints and shorts. It does NOT make that guarantee about Integer.valueOf(), which is what's being tested. Now, you and I both know that every sane implementation of Java will probably use the same code in both cases... but that's not guaranteed.



  • @random999 said:

    @morbiuswilters said:
    @derari said:
    Except for the first test, the behavior is not guaranteed by the Java specification.

    Wrong! All but the second is guaranteed.

    The link you gave doesn't support your claim.

    The link says that boxing conversions always return the same object for small ints and shorts. It does NOT make that guarantee about Integer.valueOf(), which is what's being tested. Now, you and I both know that every sane implementation of Java will probably use the same code in both cases... but that's not guaranteed.

    Does the Java spec say anything about the behavior of the standard library classes? Couldn't an implementation just return an instance of PurpleDildo from Integer.valueOf()?



  • Would someone explain some things to me? I'm not a java guy, so maybe there are some particularities of java that I need to know?


    1. How does this test illustrate that the (for example) Short caches immutable shorts? OK, so I'm not testing i == i but it looks really close to that.
    2. What would be the expected behavior (how would the assert fail) if the test were to fail? All you'd see is the assert fails; you don't get to see what a and b are.
    3. I don't know java; but I'd expect the "short test" to use a range of shorts that was something like minshort to maxshort; they're not testing negative numbers.
    4. Why test a range of numbers at all? Wouldn't you succeed or fail if you were to test with just a single number, like 3? Is the "caching" failure subject to random failures/whims of fancy?


  • @DrPepper said:

    1. How does this test illustrate that the (for example) Short caches immutable shorts? OK, so I'm not testing i == i but it looks really close to that.

    It's comparing references to instances of the Short class. Normally you never want to do == for testing comparison in Java, because it tests that references are the same, not that the actual values contained therein are the same. The equals() method is meant to be used to test equality. However, if Short.valueOf() returns identical references for two calls with the same primitive value, then this test is assuming that means it will always return the same instance of Short for the same primitive value -129 < i < 128.

    @DrPepper said:

    3. I don't know java; but I'd expect the "short test" to use a range of shorts that was something like minshort to maxshort; they're not testing negative numbers.

    This is a dumb test anyway, but the spec only guarantees that this works for shorts between -128 and 127, inclusive. And it only guarantees it for autoboxing--which is almost certainly how java.lang.Short is implementing Short.valueOf(short)--but AFAIK there's no guarantee in the spec that Short.valueOf(short) has to do this. But honestly I have no idea why they're testing this in the first damn place anyway. If your code relies on this working a particular way, it's probably really fucked up.

    @DrPepper said:

    4. Why test a range of numbers at all? Wouldn't you succeed or fail if you were to test with just a single number, like 3? Is the "caching" failure subject to random failures/whims of fancy?

    No, it shouldn't be, but you're expecting rational behavior from a test we already know to be a WTF.



  • I think the more salient point is that if you ever find yourself writing unit tests against the language provided libraries, you've probably already failed to understand the language or the API contract it offers. I mean, lets assume that you've written code that relies on all the above unit tests passing even if the language specification doesn't require them to pass. One day, you update to the latest compiler or runtime and your unit tests don't pass. Now what?



  • @Vanders said:

    One day, you update to the latest compiler or runtime and your unit tests don't pass. Now what?

    Roll back? Believe it or not, stuff like this does happen in the real world. However, I agree that it's a poor use of time to test the language like this.



  • @Vanders said:

    What, no tests that check if true is not false and that up is not down? Pfft.

    And don't forget to check charm is not strange (and top is not bottom).



  • assertTrue ( 2+2==5 ); --> test passed



  • Its not that much of a wtf... I mean, its not actually wrong, just mostly pointless.

    Although if you take the view that Oracle are untrustworthy bastards that might change how Java works at a fundamental level (however unlikely), then the tests kinda make sense.



  • @Bulb said:

    And don't forget to check charm is not strange (and top is not bottom).
     

     Ironically, I wouldn't have that much confidence that quark never change. Of course, it start to be thing so specific that you shouldn't rely on.



  • Wait, no Integer? TRWTF!



  • @eViLegion said:

    Its not that much of a wtf... I mean, its not actually wrong, just mostly pointless.

    So in your view a pointless waste of time isn't a WTF. That explains so much..

    @eViLegion said:

    Although if you take the view that Oracle are untrustworthy bastards that might change how Java works at a fundamental level (however unlikely), then the tests kinda make sense.

    No, they don't. If your code breaks because Java stops returning the same Interger object for identical int values, then your code is awful.



  • @morbiuswilters said:

    Does the Java spec say anything about the behavior of the standard library classes? Couldn't an implementation just return an instance of PurpleDildo from Integer.valueOf()?

    I want to see an implementation of the Java standard library where every function returns a String and the String class has enough methods to make a moderate amount of Java programs continue to "work".



  • @Ben L. said:

    I want to see an implementation of the Java standard library where every function returns a String and the String class has enough methods to make a moderate amount of Java programs continue to "work".

    You mean like bash, only developed by Oracle? This cannot go wrong at all!



  •  @eViLegion said:

    Its not that much of a wtf... I mean, its not actually wrong, just mostly pointless.

    Although if you take the view that Oracle are untrustworthy bastards that might change how Java works at a fundamental level (however unlikely), then the tests kinda make sense.

    I don't know much about Oracle, but I know a certain hardware company, after whom the HAL computer in 2001 was not named, who recently shipped a new version of their OS with floating point libraries that changed the behaviour of certain functions so that (in C++)

         assert(pow(10, 3) == (double)1000);

    failed. (That was part of a unit test for calculating geometric means, before you ask why on earth anyone would test that).


  • Discourse touched me in a no-no place

    @thosrtanner said:

    Floating point libraries that changed the behaviour of certain functions so that (in C++)

         assert(pow(10, 3) == (double)1000);

    failed.
    I could see that possibly failing if they were implementing it using logarithms, assuming that it was at least close. Making it precise when dealing with doubles that held integers (doubles can hold integers quite nicely) would not necessarily be a high priority; most code that does exponentiation isn't too bothered about the integer case. (Try calculating exp(log(10)*3) in your favorite language and realize that it isn't a WTF even if you think it should be…)



  • They're integers. Small integers. I'd expect problems if someone threw in a decimal point. Also, as noted, this was a WTF because it was a change in behaviour in a system library. You'd have thought they would test things like that. With - you know. Unit tests or something.

     

    And I do know about IEEE floating point. I spend a lot of time explaining to various people why our software does odd things if they try to do things with numbers like 12.3456, because of decisions made at the dawn of time which are going to spend an age unpicking.


Log in to reply