Index: /trunk/test/unit/org/CustomMatchers.java
===================================================================
--- /trunk/test/unit/org/CustomMatchers.java	(revision 11866)
+++ /trunk/test/unit/org/CustomMatchers.java	(revision 11867)
@@ -4,4 +4,5 @@
 import java.awt.geom.Point2D;
 import java.util.Collection;
+import java.util.Objects;
 import java.util.function.Predicate;
 
@@ -88,5 +89,5 @@
      */
     public static Matcher<? super Point2D> is(final Point2D expected) {
-        return new CustomTypeSafeMatcher<Point2D>("the same Point2D") {
+        return new CustomTypeSafeMatcher<Point2D>(Objects.toString(expected)) {
             @Override
             protected boolean matchesSafely(Point2D actual) {
@@ -102,5 +103,5 @@
      */
     public static Matcher<? super LatLon> is(final LatLon expected) {
-        return new CustomTypeSafeMatcher<LatLon>("the same LatLon") {
+        return new CustomTypeSafeMatcher<LatLon>(Objects.toString(expected)) {
             @Override
             protected boolean matchesSafely(LatLon actual) {
@@ -117,5 +118,5 @@
      */
     public static Matcher<? super EastNorth> is(final EastNorth expected) {
-        return new CustomTypeSafeMatcher<EastNorth>("the same EastNorth") {
+        return new CustomTypeSafeMatcher<EastNorth>(Objects.toString(expected)) {
             @Override
             protected boolean matchesSafely(EastNorth actual) {
Index: /trunk/test/unit/org/openstreetmap/josm/gui/NavigatableComponentTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/gui/NavigatableComponentTest.java	(revision 11866)
+++ /trunk/test/unit/org/openstreetmap/josm/gui/NavigatableComponentTest.java	(revision 11867)
@@ -8,8 +8,11 @@
 import java.awt.Rectangle;
 import java.awt.geom.Point2D;
+import java.util.Objects;
 
 import javax.swing.JPanel;
 
 import org.CustomMatchers;
+import org.hamcrest.CustomTypeSafeMatcher;
+import org.hamcrest.Matcher;
 import org.junit.Before;
 import org.junit.Rule;
@@ -112,5 +115,5 @@
         component.zoomTo(new LatLon(10, 10));
         Point2D shouldBeCenter = component.getPoint2D(new LatLon(10, 10));
-        // center may move 0.5 pixels for alignment, see {@link NavigatableComponent#zoomTo(EastNorth, double, boolean)}
+        // 0.5 pixel tolerance, see isAfterZoom
         assertEquals(shouldBeCenter.getX(), WIDTH / 2., 0.5);
         assertEquals(shouldBeCenter.getY(), HEIGHT / 2., 0.5);
@@ -128,8 +131,8 @@
         component.zoomToFactor(0.5);
         assertEquals(initialScale / 2, component.getScale(), 0.00000001);
-        assertThat(component.getCenter(), CustomMatchers.is(center));
+        assertThat(component.getCenter(), isAfterZoom(center, component.getScale()));
         component.zoomToFactor(2);
         assertEquals(initialScale, component.getScale(), 0.00000001);
-        assertThat(component.getCenter(), CustomMatchers.is(center));
+        assertThat(component.getCenter(), isAfterZoom(center, component.getScale()));
 
         // zoomToFactor(EastNorth, double)
@@ -137,8 +140,8 @@
         component.zoomToFactor(newCenter, 0.5);
         assertEquals(initialScale / 2, component.getScale(), 0.00000001);
-        assertEquals(newCenter, component.getCenter());
+        assertThat(component.getCenter(), isAfterZoom(newCenter, component.getScale()));
         component.zoomToFactor(newCenter, 2);
         assertEquals(initialScale, component.getScale(), 0.00000001);
-        assertEquals(newCenter, component.getCenter());
+        assertThat(component.getCenter(), isAfterZoom(newCenter, component.getScale()));
     }
 
@@ -168,15 +171,15 @@
         component.zoomToFactor(0, 0, 0.5);
         assertEquals(initialScale / 2, component.getScale(), 0.00000001);
-        assertThat(component.getEastNorth(0, 0), CustomMatchers.is(testPoint1));
+        assertThat(component.getEastNorth(0, 0), isAfterZoom(testPoint1, component.getScale()));
         component.zoomToFactor(0, 0, 2);
         assertEquals(initialScale, component.getScale(), 0.00000001);
-        assertThat(component.getEastNorth(0, 0), CustomMatchers.is(testPoint1));
+        assertThat(component.getEastNorth(0, 0), isAfterZoom(testPoint1, component.getScale()));
 
         component.zoomToFactor(200, 150, 0.5);
         assertEquals(initialScale / 2, component.getScale(), 0.00000001);
-        assertThat(component.getEastNorth(200, 150), CustomMatchers.is(testPoint2));
+        assertThat(component.getEastNorth(200, 150), isAfterZoom(testPoint2, component.getScale()));
         component.zoomToFactor(200, 150, 2);
         assertEquals(initialScale, component.getScale(), 0.00000001);
-        assertThat(component.getEastNorth(200, 150), CustomMatchers.is(testPoint2));
+        assertThat(component.getEastNorth(200, 150), isAfterZoom(testPoint2, component.getScale()));
 
     }
@@ -206,3 +209,23 @@
     }
 
+    /**
+     * Check that EastNorth is the same as expected after zooming the NavigatableComponent.
+     *
+     * Adds tolerance of 0.5 pixel for pixel grid alignment, see
+     * {@link NavigatableComponent#zoomTo(EastNorth, double, boolean)}
+     * @param expected expected
+     * @param scale current scale
+     * @return Matcher object
+     */
+    private Matcher<EastNorth> isAfterZoom(EastNorth expected, double scale) {
+        return new CustomTypeSafeMatcher<EastNorth>(Objects.toString(expected)) {
+            @Override
+            protected boolean matchesSafely(EastNorth actual) {
+                // compare pixels (east/north divided by scale)
+                return Math.abs((expected.getX() - actual.getX()) / scale) <= 0.5
+                        && Math.abs((expected.getY() - actual.getY()) / scale) <= 0.5;
+            }
+        };
+    }
+
 }
