Repository: mockito/mockito
Issue: Hard to understand argument difference between int and long
Labels: enhancement

check that
- [x] The mockito message in the stacktrace have useful information, but it didn't help
- [x] The problematic code (if that's possible) is copied here;
     Note that some configuration are impossible to mock via Mockito
- [x] Provide versions (mockito / jdk / os / any other relevant information)
- [x] Provide a [Short, Self Contained, Correct (Compilable), Example](http://sscce.org) of the issue
     (same as any question on stackoverflow.com)
- [x] Read the [contributing guide](https://github.com/mockito/mockito/blob/master/.github/CONTRIBUTING.md)

JDK: 1.8
OS: linux
mockito: master branch

Sample code:

```
package com.example;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.runners.MockitoJUnitRunner;

import java.util.HashMap;
import java.util.Map;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

public class HogeTest {
    @Test
    public void test() {
        Hello hello = mock(Hello.class);
        hello.greeting(new HashMap<String, Object>() {{
            put("hello", 3L);
        }});
        verify(hello).greeting(new HashMap<String, Object>() {{
            put("hello", 3);
        }});
    }

    public static class Hello {
        void greeting(Map<String, Object> l) {
        }
    }
}
```

Output:

```
Testing started at 8:37 AM ...
8:37:01 AM: Executing external tasks ':cleanTest :test --tests "com.example.HogeTest.test"'...
:cleanTest
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:compileTestJava
:processTestResources UP-TO-DATE
:testClasses
:test
com.example.HogeTest > test FAILED
    org.mockito.exceptions.verification.junit.ArgumentsAreDifferent at HogeTest.java:31


Argument(s) are different! Wanted:
hello.greeting(() {hello=3});
-> at com.example.HogeTest.test(HogeTest.java:31)
Actual invocation has different arguments:
hello.greeting(() {hello=3});
-> at com.example.HogeTest.test(HogeTest.java:26)

Argument(s) are different! Wanted:
hello.greeting(() {hello=3});
-> at com.example.HogeTest.test(HogeTest.java:31)
Actual invocation has different arguments:
hello.greeting(() {hello=3});
-> at com.example.HogeTest.test(HogeTest.java:26)

    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at com.example.HogeTest.test(HogeTest.java:31)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
    at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:105)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:56)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:64)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:50)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
    at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
    at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:106)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:360)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
    at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

1 test completed, 1 failed
:test FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':test'.
> There were failing tests. See the report at: file:///Users/tokuhirom/dev/mockito-sample/build/reports/tests/index.html
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 1.713 secs
There were failing tests. See the report at: file:///Users/tokuhirom/dev/mockito-sample/build/reports/tests/index.html
```

In this case, user can't understand the difference between _wanted_ and _actual_. Since 2 dumps are same!

```
Argument(s) are different! Wanted:
hello.greeting(() {hello=3});
-> at com.example.HogeTest.test(HogeTest.java:31)
Actual invocation has different arguments:
hello.greeting(() {hello=3});
-> at com.example.HogeTest.test(HogeTest.java:26)
```

If there's a _L_ suffix for long value, user can understand the difference.


Issue comments:
@tokuhirom Thanks for the report

It seems this issue holds true for older versions of mockito like 1.9.5.


Pull request review comments:
Also add an assert for multiple values in a hashmap.

Probably for multiple values it would be good to add some white-space around the `=` and maybe put them on a new-line.

Added test case for mutliple values in a hashmap.

And, added white-spaces around the '='

@tokuhirom 
for better readability better use [Collections.singletonMap(K,V)](https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#singletonMap%28K,%20V%29) here 


Patch that resolved the issue:
diff --git a/src/main/java/org/mockito/internal/matchers/text/ValuePrinter.java b/src/main/java/org/mockito/internal/matchers/text/ValuePrinter.java
index f382c39ffb..10575d3ae1 100644
--- a/src/main/java/org/mockito/internal/matchers/text/ValuePrinter.java
+++ b/src/main/java/org/mockito/internal/matchers/text/ValuePrinter.java
@@ -1,6 +1,7 @@
 package org.mockito.internal.matchers.text;
 
 import java.util.Iterator;
+import java.util.Map;
 
 import static java.lang.String.valueOf;
 
@@ -21,6 +22,16 @@ public static String print(Object value) {
             return "\"" + value + "\"";
         } else if (value instanceof Character) {
             return printChar((Character) value);
+        } else if (value instanceof Long) {
+            return value + "L";
+        } else if (value instanceof Double) {
+            return value + "d";
+        } else if (value instanceof Float) {
+            return value + "f";
+        } else if (value instanceof Byte) {
+            return String.format("0x%02X", (Byte) value);
+        } else if (value instanceof Map) {
+            return printMap((Map) value);
         } else if (value.getClass().isArray()) {
             return printValues("[", ", ", "]", new org.mockito.internal.matchers.text.ArrayIterator(value));
         } else if (value instanceof FormattedText) {
@@ -30,6 +41,19 @@ public static String print(Object value) {
         return descriptionOf(value);
     }
 
+    private static String printMap(Map<?,?> map) {
+        StringBuilder result = new StringBuilder();
+        Iterator<? extends Map.Entry<?, ?>> iterator = map.entrySet().iterator();
+        while (iterator.hasNext()) {
+            Map.Entry<?, ?> entry = iterator.next();
+            result.append(print(entry.getKey())).append(" = ").append(print(entry.getValue()));
+            if (iterator.hasNext()) {
+                result.append(", ");
+            }
+        }
+        return "{" + result.toString() + "}";
+    }
+
     /**
      * Print values in a nice format, e.g. (1, 2, 3)
      *


Test patch:
diff --git a/src/test/java/org/mockito/internal/matchers/EqualsTest.java b/src/test/java/org/mockito/internal/matchers/EqualsTest.java
index d0d92d6a75..6664f68bb7 100644
--- a/src/test/java/org/mockito/internal/matchers/EqualsTest.java
+++ b/src/test/java/org/mockito/internal/matchers/EqualsTest.java
@@ -39,7 +39,7 @@ public void shouldDescribeWithExtraTypeInfo() throws Exception {
     public void shouldDescribeWithExtraTypeInfoOfLong() throws Exception {
         String descStr = new Equals(100L).toStringWithType();
         
-        assertEquals("(Long) 100", descStr);
+        assertEquals("(Long) 100L", descStr);
     }
 
     @Test
diff --git a/src/test/java/org/mockito/internal/matchers/MatchersPrinterTest.java b/src/test/java/org/mockito/internal/matchers/MatchersPrinterTest.java
index efbf377621..eaeea5ec5e 100644
--- a/src/test/java/org/mockito/internal/matchers/MatchersPrinterTest.java
+++ b/src/test/java/org/mockito/internal/matchers/MatchersPrinterTest.java
@@ -36,7 +36,7 @@ public void shouldDescribeTypeInfoOnlyMarkedMatchers() {
         //when
         String line = printer.getArgumentsLine((List) Arrays.asList(new Equals(1L), new Equals(2)), PrintSettings.verboseMatchers(1));
         //then
-        assertEquals("(1, (Integer) 2);", line);
+        assertEquals("(1L, (Integer) 2);", line);
     }
 
     @Test
@@ -44,7 +44,7 @@ public void shouldDescribeStringMatcher() {
         //when
         String line = printer.getArgumentsLine((List) Arrays.asList(new Equals(1L), new Equals("x")), PrintSettings.verboseMatchers(1));
         //then
-        assertEquals("(1, (String) \"x\");", line);
+        assertEquals("(1L, (String) \"x\");", line);
     }
 
     @Test
@@ -52,7 +52,7 @@ public void shouldGetVerboseArgumentsInBlock() {
         //when
         String line = printer.getArgumentsBlock((List) Arrays.asList(new Equals(1L), new Equals(2)), PrintSettings.verboseMatchers(0, 1));
         //then
-        assertEquals("(\n    (Long) 1,\n    (Integer) 2\n);", line);
+        assertEquals("(\n    (Long) 1L,\n    (Integer) 2\n);", line);
     }
 
     @Test
@@ -60,6 +60,6 @@ public void shouldGetVerboseArgumentsEvenIfSomeMatchersAreNotVerbose() {
         //when
         String line = printer.getArgumentsLine((List) Arrays.asList(new Equals(1L), NotNull.NOT_NULL), PrintSettings.verboseMatchers(0));
         //then
-        assertEquals("((Long) 1, notNull());", line);
+        assertEquals("((Long) 1L, notNull());", line);
     }
 }
\ No newline at end of file
diff --git a/src/test/java/org/mockito/internal/matchers/text/ValuePrinterTest.java b/src/test/java/org/mockito/internal/matchers/text/ValuePrinterTest.java
index 1ecc8cfb3e..ac7235b345 100644
--- a/src/test/java/org/mockito/internal/matchers/text/ValuePrinterTest.java
+++ b/src/test/java/org/mockito/internal/matchers/text/ValuePrinterTest.java
@@ -3,6 +3,8 @@
 
 import org.junit.Test;
 
+import java.util.LinkedHashMap;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.internal.matchers.text.ValuePrinter.print;
@@ -14,7 +16,26 @@ public void prints_values() throws Exception {
         assertEquals("null", print(null));
         assertEquals("\"str\"", print("str"));
         assertEquals("\"x\ny\"", print("x\ny"));
+        assertEquals("3", print(3));
+        assertEquals("3L", print(3L));
+        assertEquals("3.14d", print(3.14d));
+        assertEquals("3.14f", print(3.14f));
         assertEquals("[1, 2]", print(new int[]{1, 2}));
+        assertEquals("{\"foo\" = 2L}", print(new LinkedHashMap<String, Object>() {
+            {
+                put("foo", 2L);
+            }
+        }));
+        assertEquals("{\"byte\" = 0x01, \"short\" = 2, \"int\" = 3, \"long\" = 4L, \"float\" = 2.71f, \"double\" = 3.14d}", print(new LinkedHashMap<String, Object>() {
+            {
+                put("byte", (byte)1);
+                put("short", (short)2);
+                put("int", 3);
+                put("long", 4L);
+                put("float", 2.71f);
+                put("double", 3.14d);
+            }
+        }));
         assertTrue(print(new UnsafeToString()).contains("UnsafeToString"));
         assertEquals("ToString", print(new ToString()));
         assertEquals("formatted", print(new FormattedText("formatted")));
diff --git a/src/test/java/org/mockitousage/verification/DescriptiveMessagesWhenVerificationFailsTest.java b/src/test/java/org/mockitousage/verification/DescriptiveMessagesWhenVerificationFailsTest.java
index 1a2a10cde4..c75b6b05d3 100644
--- a/src/test/java/org/mockitousage/verification/DescriptiveMessagesWhenVerificationFailsTest.java
+++ b/src/test/java/org/mockitousage/verification/DescriptiveMessagesWhenVerificationFailsTest.java
@@ -374,7 +374,7 @@ public void should_print_method_name_and_arguments_of_other_interactions_with_di
             assertThat(e)
                 .hasMessageContaining("iMethods.threeArgumentMethod(12, foo, \"xx\")")
                 .hasMessageContaining("iMethods.arrayMethod([\"a\", \"b\", \"c\"])")
-                .hasMessageContaining("iMethods.forByte(25)");
+                .hasMessageContaining("iMethods.forByte(0x19)");
         }
     }
 
diff --git a/src/test/java/org/mockitousage/verification/PrintingVerboseTypesWithArgumentsTest.java b/src/test/java/org/mockitousage/verification/PrintingVerboseTypesWithArgumentsTest.java
index 233ea4dabb..2c44d9bb44 100644
--- a/src/test/java/org/mockitousage/verification/PrintingVerboseTypesWithArgumentsTest.java
+++ b/src/test/java/org/mockitousage/verification/PrintingVerboseTypesWithArgumentsTest.java
@@ -42,7 +42,7 @@ public void should_not_report_argument_types_when_to_string_is_the_same() {
             //then
             assertThat(e)
                 .hasMessageContaining("withLong((Integer) 100);")
-                .hasMessageContaining("withLong((Long) 100);");
+                .hasMessageContaining("withLong((Long) 100L);");
         }
     }
 
@@ -60,7 +60,7 @@ public void should_show_the_type_of_only_the_argument_that_doesnt_match() {
             //then
             assertThat(e)
                 .hasMessageContaining("withLongAndInt((Integer) 100, 200)")
-                .hasMessageContaining("withLongAndInt((Long) 100, 200)");
+                .hasMessageContaining("withLongAndInt((Long) 100L, 200)");
         }
     }
 
@@ -78,7 +78,7 @@ public void should_show_the_type_of_the_mismatching_argument_when_output_descrip
             //then
             Assertions.assertThat(e.getMessage())
                       .contains("withLongAndInt(\n" +
-                                        "    (Long) 100,\n" +
+                                        "    (Long) 100L,\n" +
                                         "    200\n" +
                                         ")")
                       .contains("withLongAndInt(\n" +
@@ -101,8 +101,8 @@ public void should_not_show_types_when_argument_value_is_different() {
         } catch (ArgumentsAreDifferent e) {
             //then
             assertThat(e)
-                .hasMessageContaining("withLongAndInt(100, 200)")
-                .hasMessageContaining("withLongAndInt(100, 230)");
+                .hasMessageContaining("withLongAndInt(100L, 200)")
+                .hasMessageContaining("withLongAndInt(100L, 230)");
         }
     }