Index: /trunk/src/org/openstreetmap/josm/actions/AbstractMergeAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/AbstractMergeAction.java	(revision 14331)
+++ /trunk/src/org/openstreetmap/josm/actions/AbstractMergeAction.java	(revision 14332)
@@ -110,8 +110,5 @@
         pnl.add(new JLabel(label), GBC.eol());
         pnl.add(layerList, GBC.eol().fill(GBC.HORIZONTAL));
-        if (GraphicsEnvironment.isHeadless()) {
-            // return first layer in headless mode, for unit tests
-            return targetLayers[0];
-        }
+
         ExtendedDialog ed = new ExtendedDialog(MainApplication.getMainFrame(), title, buttonText, tr("Cancel"));
         ed.setButtonIcons(buttonIcon, "cancel");
@@ -131,7 +128,5 @@
         String message = tr("<html>There are no layers the source layer<br>''{0}''<br>could be merged to.</html>",
                 Utils.escapeReservedCharactersHTML(sourceLayer.getName()));
-        if (!GraphicsEnvironment.isHeadless()) {
-            JOptionPane.showMessageDialog(MainApplication.getMainFrame(), message, tr("No target layers"), JOptionPane.WARNING_MESSAGE);
-        }
+        JOptionPane.showMessageDialog(MainApplication.getMainFrame(), message, tr("No target layers"), JOptionPane.WARNING_MESSAGE);
     }
 }
Index: /trunk/src/org/openstreetmap/josm/gui/layer/gpx/DownloadWmsAlongTrackAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/gpx/DownloadWmsAlongTrackAction.java	(revision 14331)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/gpx/DownloadWmsAlongTrackAction.java	(revision 14332)
@@ -118,7 +118,5 @@
         List<AbstractTileSourceLayer> targetLayers = MainApplication.getLayerManager().getLayersOfType(AbstractTileSourceLayer.class);
         if (targetLayers.isEmpty()) {
-            if (!GraphicsEnvironment.isHeadless()) {
-                warnNoImageryLayers();
-            }
+            warnNoImageryLayers();
             return null;
         }
Index: /trunk/test/unit/org/openstreetmap/josm/actions/MergeLayerActionTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/actions/MergeLayerActionTest.java	(revision 14331)
+++ /trunk/test/unit/org/openstreetmap/josm/actions/MergeLayerActionTest.java	(revision 14332)
@@ -1,4 +1,7 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.actions;
+
+import javax.swing.JLabel;
+import javax.swing.JPanel;
 
 import static org.junit.Assert.assertEquals;
@@ -9,8 +12,15 @@
 import org.junit.Test;
 import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.ExtendedDialog;
 import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.gui.layer.LayerManagerTest.TestLayer;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.gui.widgets.JosmComboBox;
+import org.openstreetmap.josm.TestUtils;
 import org.openstreetmap.josm.testutils.JOSMTestRules;
+import org.openstreetmap.josm.testutils.mockers.ExtendedDialogMocker;
+import org.openstreetmap.josm.testutils.mockers.JOptionPaneSimpleMocker;
+
+import com.google.common.collect.ImmutableMap;
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
@@ -27,4 +37,19 @@
     @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
     public JOSMTestRules test = new JOSMTestRules().main();
+
+    /**
+     * MergeLayerExtendedDialog mocker.
+     */
+    public static class MergeLayerExtendedDialogMocker extends ExtendedDialogMocker {
+        @Override
+        protected void act(final ExtendedDialog instance) {
+            ((JosmComboBox<?>) ((JPanel) this.getContent(instance)).getComponent(1)).setSelectedIndex(0);
+        }
+
+        @Override
+        protected String getString(final ExtendedDialog instance) {
+            return ((JLabel) ((JPanel) this.getContent(instance)).getComponent(0)).getText();
+        }
+    }
 
     private MergeLayerAction action;
@@ -58,9 +83,19 @@
     @Test
     public void testMergeNoTargetLayer() {
-        OsmDataLayer layer = new OsmDataLayer(new DataSet(), "", null);
+        TestUtils.assumeWorkingJMockit();
+        final JOptionPaneSimpleMocker jopsMocker = new JOptionPaneSimpleMocker(
+            ImmutableMap.<String, Object>of("<html>There are no layers the source layer<br>'onion'<br>could be merged to.</html>", 0)
+        );
+
+        OsmDataLayer layer = new OsmDataLayer(new DataSet(), "onion", null);
         MainApplication.getLayerManager().addLayer(layer);
         assertEquals(1, MainApplication.getLayerManager().getLayers().size());
         assertNull(action.merge(layer));
         assertEquals(1, MainApplication.getLayerManager().getLayers().size());
+
+        assertEquals(1, jopsMocker.getInvocationLog().size());
+        Object[] invocationLogEntry = jopsMocker.getInvocationLog().get(0);
+        assertEquals(0, (int) invocationLogEntry[0]);
+        assertEquals("No target layers", invocationLogEntry[2]);
     }
 
@@ -71,4 +106,8 @@
     @Test
     public void testMergeTwoEmptyLayers() throws Exception {
+        TestUtils.assumeWorkingJMockit();
+        final MergeLayerExtendedDialogMocker edMocker = new MergeLayerExtendedDialogMocker();
+        edMocker.getMockResultMap().put("Please select the target layer.", "Merge");
+
         OsmDataLayer layer1 = new OsmDataLayer(new DataSet(), "1", null);
         OsmDataLayer layer2 = new OsmDataLayer(new DataSet(), "2", null);
@@ -78,4 +117,9 @@
         action.merge(layer2).get();
         assertEquals(1, MainApplication.getLayerManager().getLayers().size());
+
+        assertEquals(1, edMocker.getInvocationLog().size());
+        Object[] invocationLogEntry = edMocker.getInvocationLog().get(0);
+        assertEquals(1, (int) invocationLogEntry[0]);
+        assertEquals("Select target layer", invocationLogEntry[2]);
     }
 }
Index: /trunk/test/unit/org/openstreetmap/josm/gui/layer/gpx/DownloadWmsAlongTrackActionTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/gui/layer/gpx/DownloadWmsAlongTrackActionTest.java	(revision 14331)
+++ /trunk/test/unit/org/openstreetmap/josm/gui/layer/gpx/DownloadWmsAlongTrackActionTest.java	(revision 14332)
@@ -3,4 +3,5 @@
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
@@ -10,4 +11,5 @@
 import org.junit.Rule;
 import org.junit.Test;
+import org.openstreetmap.josm.actions.MergeLayerActionTest.MergeLayerExtendedDialogMocker;
 import org.openstreetmap.josm.data.gpx.GpxData;
 import org.openstreetmap.josm.gui.MainApplication;
@@ -15,6 +17,10 @@
 import org.openstreetmap.josm.gui.layer.TMSLayer;
 import org.openstreetmap.josm.gui.layer.gpx.DownloadWmsAlongTrackAction.PrecacheWmsTask;
+import org.openstreetmap.josm.TestUtils;
 import org.openstreetmap.josm.testutils.JOSMTestRules;
 import org.openstreetmap.josm.testutils.TileSourceRule;
+import org.openstreetmap.josm.testutils.mockers.JOptionPaneSimpleMocker;
+
+import com.google.common.collect.ImmutableMap;
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
@@ -37,5 +43,15 @@
     @Test
     public void testNoLayer() {
+        TestUtils.assumeWorkingJMockit();
+        final JOptionPaneSimpleMocker jopsMocker = new JOptionPaneSimpleMocker(
+            ImmutableMap.<String, Object>of("There are no imagery layers.", 0)
+        );
+
         assertNull(new DownloadWmsAlongTrackAction(new GpxData()).createTask());
+
+        assertEquals(1, jopsMocker.getInvocationLog().size());
+        Object[] invocationLogEntry = jopsMocker.getInvocationLog().get(0);
+        assertEquals(0, (int) invocationLogEntry[0]);
+        assertEquals("No imagery layers", invocationLogEntry[2]);
     }
 
@@ -46,4 +62,8 @@
     @Test
     public void testTMSLayer() throws Exception {
+        TestUtils.assumeWorkingJMockit();
+        final MergeLayerExtendedDialogMocker edMocker = new MergeLayerExtendedDialogMocker();
+        edMocker.getMockResultMap().put("Please select the imagery layer.", "Download");
+
         final TileSourceRule tileSourceRule = this.test.getTileSourceRule();
 
@@ -65,4 +85,9 @@
             MainApplication.getLayerManager().removeLayer(layer);
         }
+
+        assertEquals(1, edMocker.getInvocationLog().size());
+        Object[] invocationLogEntry = edMocker.getInvocationLog().get(0);
+        assertEquals(1, (int) invocationLogEntry[0]);
+        assertEquals("Select imagery layer", invocationLogEntry[2]);
     }
 }
Index: /trunk/test/unit/org/openstreetmap/josm/testutils/mockers/ExtendedDialogMocker.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/testutils/mockers/ExtendedDialogMocker.java	(revision 14331)
+++ /trunk/test/unit/org/openstreetmap/josm/testutils/mockers/ExtendedDialogMocker.java	(revision 14332)
@@ -11,4 +11,5 @@
 import java.util.WeakHashMap;
 
+import org.openstreetmap.josm.TestUtils;
 import org.openstreetmap.josm.gui.ExtendedDialog;
 import org.openstreetmap.josm.tools.Logging;
@@ -108,4 +109,14 @@
     }
 
+    /**
+     * Target for overriding, similar to {@link #getMockResult} except with the implication it will only
+     * be invoked once per dialog display, therefore ideal opportunity to perform any mutating actions,
+     * e.g. making a selection on a widget.
+     * @param instance dialog instance
+     */
+    protected void act(final ExtendedDialog instance) {
+        // Override in sub-classes
+    }
+
     protected Object[] getInvocationLogEntry(final ExtendedDialog instance, final int mockResult) {
         return new Object[] {
@@ -114,4 +125,17 @@
             instance.getTitle()
         };
+    }
+
+    /**
+     * A convenience method to access {@link ExtendedDialog#content} without exception-catching boilerplate
+     * @param instance dialog instance
+     * @return dialog content component
+     */
+    protected Component getContent(final ExtendedDialog instance) {
+        try {
+            return (Component) TestUtils.getPrivateField(instance, "content");
+        } catch (ReflectiveOperationException e) {
+            throw new RuntimeException(e);
+        }
     }
 
@@ -130,4 +154,5 @@
             try {
                 final ExtendedDialog instance = invocation.getInvokedInstance();
+                this.act(instance);
                 final int mockResult = this.getMockResult(instance);
                 // TODO check validity of mockResult?
Index: /trunk/test/unit/org/openstreetmap/josm/testutils/mockers/HelpAwareOptionPaneMocker.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/testutils/mockers/HelpAwareOptionPaneMocker.java	(revision 14331)
+++ /trunk/test/unit/org/openstreetmap/josm/testutils/mockers/HelpAwareOptionPaneMocker.java	(revision 14332)
@@ -76,4 +76,14 @@
         }
         return this.getMockResultMap().get(messageString);
+    }
+
+    /**
+     * Target for overriding, similar to {@link #getMockResultForMessage} except with the implication it
+     * will only be invoked once per dialog display, therefore ideal opportunity to perform any mutating
+     * actions, e.g. making a selection on a widget.
+     * @param message message
+     */
+    protected void act(final Object message) {
+        // Override in sub-classes
     }
 
@@ -134,4 +144,5 @@
     ) {
         try {
+            this.act(msg);
             final Object result = this.getMockResultForMessage(msg);
 
Index: /trunk/test/unit/org/openstreetmap/josm/testutils/mockers/JOptionPaneSimpleMocker.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/testutils/mockers/JOptionPaneSimpleMocker.java	(revision 14331)
+++ /trunk/test/unit/org/openstreetmap/josm/testutils/mockers/JOptionPaneSimpleMocker.java	(revision 14332)
@@ -134,4 +134,14 @@
     }
 
+    /**
+     * Target for overriding, similar to {@link #getMockResultForMessage} except with the implication it
+     * will only be invoked once per dialog display, therefore ideal opportunity to perform any mutating
+     * actions, e.g. making a selection on a widget.
+     * @param message message
+     */
+    protected void act(final Object message) {
+        // Override in sub-classes
+    }
+
     protected Object[] getInvocationLogEntry(
         final Object message,
@@ -162,4 +172,5 @@
     ) {
         try {
+            this.act(message);
             final Object result = this.getMockResultForMessage(message);
             if (selectionValues == null) {
@@ -216,4 +227,5 @@
     ) {
         try {
+            this.act(message);
             // why look up a "result" for a message dialog which can only have one possible result? it's
             // a good opportunity to assert its contents
@@ -263,4 +275,5 @@
     ) {
         try {
+            this.act(message);
             final Object result = this.getMockResultForMessage(message);
             if (!(result instanceof Integer && Ints.contains(optionTypePermittedResults.get(optionType), (int) result))) {
