Search code examples
javagradleintellij-ideajunitguava

JUnit test passes in Run mode, but fails in debug mode?


Introduction

When I run this test in Run mode

@Test
public void testGetFinalOutput() {
    final ObjectLocator dut = new ObjectLocator(ImmutableMap.of(
            TEST_ITEM, new Coordinates(1,1)));

    Assert.assertTrue(dut.getFinalOutput(1, 1).isPresent());
}

This will run and passes the assertion.

If I run the same test in Debug mode, I get the following error and stacktrace:

java.lang.ExceptionInInitializerError
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalArgumentException: Multiple entries with same key: (2, 0)=[GameObject{blocking=true, grabbable=false, sprite=ObjectGeometry{foreColor=java.awt.Color[r=255,g=255,b=255], backColor=java.awt.Color[r=0,g=0,b=0], imgChar=AMPERSAND}, name=test wall, desires=[], detailedDescription=This is a test wall, uuid=6e84f9a5-5039-40a2-acc1-793d50ebded4}] and (2, 0)=[GameObject{blocking=true, grabbable=false, sprite=ObjectGeometry{foreColor=java.awt.Color[r=255,g=255,b=255], backColor=java.awt.Color[r=0,g=0,b=0], imgChar=AMPERSAND}, name=test wall, desires=[], detailedDescription=This is a test wall, uuid=32ad0809-4252-4883-896a-a3b228c9c250}]
    at com.google.common.collect.ImmutableMap.conflictException(ImmutableMap.java:211)
    at com.google.common.collect.ImmutableMap.checkNoConflict(ImmutableMap.java:205)
    at com.google.common.collect.RegularImmutableMap.checkNoConflictInKeyBucket(RegularImmutableMap.java:146)
    at com.google.common.collect.RegularImmutableMap.fromEntryArray(RegularImmutableMap.java:109)
    at com.google.common.collect.ImmutableMap$Builder.build(ImmutableMap.java:390)
    at com.google.common.collect.ImmutableSetMultimap.fromMapEntries(ImmutableSetMultimap.java:420)
    at com.google.common.collect.ImmutableSetMultimap.copyOf(ImmutableSetMultimap.java:381)
    at com.google.common.collect.ImmutableSetMultimap.copyOf(ImmutableSetMultimap.java:363)
    at location.ObjectLocator.mergeValues(ObjectLocator.java:147)
    at location.ObjectLocator.union(ObjectLocator.java:165)
    at location.ObjectLocator.union(ObjectLocator.java:60)
    at generation.BuildingUtils.runWalls(BuildingUtils.java:125)
    at generation.BuildingUtils.buildClosedPolygon(BuildingUtils.java:139)
    at generation.BuildingUtils.buildRectangle(BuildingUtils.java:67)
    at location.ObjectLocatorTest.<clinit>(ObjectLocatorTest.java:39)
    ... 46 more

Details

The line 39 in ObjectLocatorTest.java which triggers this is part of an initialization of a static field:

private static final ObjectLocator VERTICAL = BuildingUtils.buildRectangle(
        TEST_WALL_FACTORY, TEST_FLOOR_FACTORY,
        3,5).translate(1,0);

Here's my mergeValues in ObjectLocator.java:

private static <K,V> ImmutableMultimap<K,V> mergeValues(final Multimap<K, V> mapA, final Multimap<K,V> mapB) {
    final Multimap<K,V> retVal = HashMultimap.create();
    for(Map.Entry<K, V> entry : mapA.entries()) {
        retVal.put(entry.getKey(), entry.getValue());
    }
    for(Map.Entry<K, V> entry : mapB.entries()) {
        retVal.put(entry.getKey(), entry.getValue());
    }
    return ImmutableSetMultimap.copyOf(retVal);
}

Where the return ImmutableSetMultimap.copyOf(retVal);is on line 147. Shouldn't a Multimap be able to handle "Multiple entries with same key", as the stacktrace complains about?

Versions

  • I'm running this in IntelliJ IDEA Ultimate 2020.2.
  • I'm using guava 30.1-jre
  • I'm using Java 8

Solution

  • In your key class, you overrode Object's equals(Object obj) but not hashCode().

    Override both properly.