Index: trunk/test/unit/org/openstreetmap/josm/gui/datatransfer/ClipboardUtilsTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/datatransfer/ClipboardUtilsTest.java	(revision 14411)
+++ trunk/test/unit/org/openstreetmap/josm/gui/datatransfer/ClipboardUtilsTest.java	(revision 14412)
@@ -7,4 +7,5 @@
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
 
 import java.awt.GraphicsEnvironment;
@@ -118,5 +119,5 @@
     @Test
     public void testSystemSelectionDoesNotFail() {
-        assertTrue(GraphicsEnvironment.isHeadless());
+        assumeTrue(GraphicsEnvironment.isHeadless());
         assertNull(ClipboardUtils.getSystemSelection());
     }
Index: trunk/test/unit/org/openstreetmap/josm/gui/help/HelpBrowserTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/help/HelpBrowserTest.java	(revision 14411)
+++ trunk/test/unit/org/openstreetmap/josm/gui/help/HelpBrowserTest.java	(revision 14412)
@@ -13,8 +13,12 @@
 import org.openstreetmap.josm.testutils.mockers.JOptionPaneSimpleMocker;
 import org.openstreetmap.josm.tools.LanguageInfo.LocaleType;
+import org.openstreetmap.josm.tools.PlatformHook;
+import org.openstreetmap.josm.tools.PlatformManager;
 
 import com.google.common.collect.ImmutableMap;
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import mockit.Expectations;
+import mockit.Injectable;
 
 /**
@@ -91,17 +95,60 @@
 
     /**
-     * Unit test of {@link HelpBrowser.EditAction} class.
-     */
-    @Test
-    public void testEditAction() {
-        TestUtils.assumeWorkingJMockit();
+     * Unit test of {@link HelpBrowser.EditAction} class handling a null url.
+     * @param mockPlatformHook platform hook mock
+     * @throws Exception  in case of error
+     */
+    @Test
+    public void testEditActionNull(@Injectable final PlatformHook mockPlatformHook) throws Exception {
+        TestUtils.assumeWorkingJMockit();
+        new Expectations(PlatformManager.class) {{
+            PlatformManager.getPlatform(); result = mockPlatformHook; minTimes = 0;
+        }};
+        new Expectations() {{
+            // should not be called
+            mockPlatformHook.openUrl((String) any); times = 0;
+        }};
+
         IHelpBrowser browser = newHelpBrowser();
         assertNull(browser.getUrl());
         new HelpBrowser.EditAction(browser).actionPerformed(null);
-
+    }
+
+    /**
+     * Unit test of {@link HelpBrowser.EditAction} class handling an "internal" url.
+     * @param mockPlatformHook platform hook mock
+     * @throws Exception  in case of error
+     */
+    @Test
+    public void testEditActionInternal(@Injectable final PlatformHook mockPlatformHook) throws Exception {
+        TestUtils.assumeWorkingJMockit();
+        new Expectations(PlatformManager.class) {{
+            PlatformManager.getPlatform(); result = mockPlatformHook;
+        }};
+        new Expectations() {{
+            mockPlatformHook.openUrl(URL_2 + "?action=edit"); result = null; times = 1;
+        }};
+
+        IHelpBrowser browser = newHelpBrowser();
         browser.openUrl(URL_2);
         assertEquals(URL_2, browser.getUrl());
         new HelpBrowser.EditAction(browser).actionPerformed(null);
-
+    }
+
+    /**
+     * Unit test of {@link HelpBrowser.EditAction} class handling an "external" url.
+     * @param mockPlatformHook platform hook mock
+     * @throws Exception  in case of error
+     */
+    @Test
+    public void testEditActionExternal(@Injectable final PlatformHook mockPlatformHook) throws Exception {
+        TestUtils.assumeWorkingJMockit();
+        new Expectations(PlatformManager.class) {{
+            PlatformManager.getPlatform(); result = mockPlatformHook; minTimes = 0;
+        }};
+        new Expectations() {{
+            // should not be called
+            mockPlatformHook.openUrl((String) any); times = 0;
+        }};
         final JOptionPaneSimpleMocker jopsMocker = new JOptionPaneSimpleMocker(
             ImmutableMap.<String, Object>of(
@@ -113,4 +160,5 @@
         );
 
+        IHelpBrowser browser = newHelpBrowser();
         browser.openUrl(URL_3);
         assertEquals(URL_3, browser.getUrl());
@@ -125,7 +173,17 @@
     /**
      * Unit test of {@link HelpBrowser.OpenInBrowserAction} class.
-     */
-    @Test
-    public void testOpenInBrowserAction() {
+     * @param mockPlatformHook platform hook mock
+     * @throws Exception  in case of error
+     */
+    @Test
+    public void testOpenInBrowserAction(@Injectable final PlatformHook mockPlatformHook) throws Exception {
+        TestUtils.assumeWorkingJMockit();
+        new Expectations(PlatformManager.class) {{
+            PlatformManager.getPlatform(); result = mockPlatformHook;
+        }};
+        new Expectations() {{
+            mockPlatformHook.openUrl(URL_1); result = null; times = 1;
+        }};
+
         IHelpBrowser browser = newHelpBrowser();
         browser.openUrl(URL_1);
Index: trunk/test/unit/org/openstreetmap/josm/gui/layer/markerlayer/WebMarkerTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/layer/markerlayer/WebMarkerTest.java	(revision 14411)
+++ trunk/test/unit/org/openstreetmap/josm/gui/layer/markerlayer/WebMarkerTest.java	(revision 14412)
@@ -4,5 +4,4 @@
 import static org.junit.Assert.assertEquals;
 
-import java.net.MalformedURLException;
 import java.net.URL;
 
@@ -10,7 +9,14 @@
 import org.junit.Test;
 import org.openstreetmap.josm.JOSMFixture;
+import org.openstreetmap.josm.TestUtils;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.gpx.GpxData;
 import org.openstreetmap.josm.data.gpx.WayPoint;
+import org.openstreetmap.josm.tools.PlatformManager;
+import org.openstreetmap.josm.tools.PlatformHook;
+
+
+import mockit.Expectations;
+import mockit.Injectable;
 
 /**
@@ -29,8 +35,17 @@
     /**
      * Unit test of {@link WebMarker#WebMarker}.
-     * @throws MalformedURLException never
+     * @param mockPlatformHook platform hook mock
+     * @throws Exception  in case of error
      */
     @Test
-    public void testWebMarker() throws MalformedURLException {
+    public void testWebMarker(@Injectable final PlatformHook mockPlatformHook) throws Exception {
+        TestUtils.assumeWorkingJMockit();
+        new Expectations(PlatformManager.class) {{
+            PlatformManager.getPlatform(); result = mockPlatformHook;
+        }};
+        new Expectations() {{
+            mockPlatformHook.openUrl("http://example.com"); result = null; times = 1;
+        }};
+
         WebMarker marker = new WebMarker(
                 LatLon.ZERO,
Index: trunk/test/unit/org/openstreetmap/josm/tools/PlatformHookWindowsTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/tools/PlatformHookWindowsTest.java	(revision 14411)
+++ trunk/test/unit/org/openstreetmap/josm/tools/PlatformHookWindowsTest.java	(revision 14412)
@@ -10,4 +10,5 @@
 import static org.junit.Assert.fail;
 
+import java.awt.Desktop;
 import java.io.File;
 import java.io.IOException;
@@ -20,7 +21,11 @@
 import org.junit.Test;
 import org.openstreetmap.josm.JOSMFixture;
+import org.openstreetmap.josm.TestUtils;
 import org.openstreetmap.josm.io.remotecontrol.RemoteControlHttpsServer;
 import org.openstreetmap.josm.io.remotecontrol.RemoteControlTest;
 import org.openstreetmap.josm.spi.preferences.Config;
+
+import mockit.Expectations;
+import mockit.Injectable;
 
 /**
@@ -117,19 +122,47 @@
 
     /**
-     * Test method for {@code PlatformHookWindows#openUrl}
+     * Test method for {@code PlatformHookWindows#openUrl} when Desktop works as expected
+     * @param mockDesktop desktop mock
      * @throws IOException if an error occurs
      */
     @Test
-    public void testOpenUrl() throws IOException {
-        if (PlatformManager.isPlatformWindows()) {
-            hook.openUrl(Config.getUrls().getJOSMWebsite());
-        } else {
-            try {
-                hook.openUrl(Config.getUrls().getJOSMWebsite());
-                fail("Expected IOException");
-            } catch (IOException e) {
-                Logging.info(e.getMessage());
-            }
-        }
+    public void testOpenUrlSuccess(@Injectable final Desktop mockDesktop) throws IOException {
+        TestUtils.assumeWorkingJMockit();
+        new Expectations(Desktop.class) {{
+            // real implementation would raise HeadlessException
+            Desktop.getDesktop(); result = mockDesktop; times = 1;
+        }};
+        new Expectations() {{
+            mockDesktop.browse(withNotNull()); times = 1;
+        }};
+
+        hook.openUrl(Config.getUrls().getJOSMWebsite());
+    }
+
+    /**
+     * Test method for {@code PlatformHookWindows#openUrl} when Desktop fails
+     * @param mockDesktop desktop mock
+     * @throws IOException if an error occurs
+     */
+    @Test
+    public void testOpenUrlFallback(@Injectable final Desktop mockDesktop) throws IOException {
+        TestUtils.assumeWorkingJMockit();
+        new Expectations(Desktop.class) {{
+            // real implementation would raise HeadlessException
+            Desktop.getDesktop(); result = mockDesktop; times = 1;
+        }};
+        new Expectations() {{
+            mockDesktop.browse(withNotNull()); result = new IOException(); times = 1;
+        }};
+        final Runtime anyRuntime = Runtime.getRuntime();
+        new Expectations(Runtime.class) {{
+            anyRuntime.exec(new String[] {"rundll32", "url.dll,FileProtocolHandler", Config.getUrls().getJOSMWebsite()});
+            result = null;
+            times = 1;
+            // prevent a non-matching invocation being executed
+            anyRuntime.exec((String[]) withNotNull()); result = null; times = 0;
+        }};
+
+        hook.openUrl(Config.getUrls().getJOSMWebsite());
     }
 
