diff --git a/tests/mollom.test b/tests/mollom.test
index 72d6382..5079d52 100644
--- a/tests/mollom.test
+++ b/tests/mollom.test
@@ -870,6 +870,8 @@ class MollomInstallationTestCase extends MollomWebTestCase {
  * Tests low-level XML-RPC communication with Mollom servers.
  */
 class MollomResponseTestCase extends MollomWebTestCase {
+  protected $profile = 'testing';
+
   public static function getInfo() {
     return array(
       'name' => 'Server responses',
@@ -1054,6 +1056,26 @@ class MollomResponseTestCase extends MollomWebTestCase {
   }
 }
 
+/**
+ * Tests low-level communication with local fake Mollom server.
+ */
+class MollomResponseLocalTestCase extends MollomResponseTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Server responses (local)',
+      'description' => 'Tests that local fake Mollom server responses match expectations.',
+      'group' => 'Mollom',
+    );
+  }
+
+  function setUp() {
+    // Enable testing server implementation.
+    parent::setUp(array('mollom_test'));
+    // Re-route Mollom communication to this testing site.
+    variable_set('mollom_servers', array($GLOBALS['base_url'] . '/xmlrpc.php?version='));
+  }
+}
+
 class MollomAccessTestCase extends MollomWebTestCase {
   public static function getInfo() {
     return array(
diff --git a/tests/mollom_test.module b/tests/mollom_test.module
index 842e167..d8d9192 100644
--- a/tests/mollom_test.module
+++ b/tests/mollom_test.module
@@ -97,9 +97,15 @@ function mollom_test_check_content($data) {
       $quality = 1;
     }
     else {
-      $response['spam'] = MOLLOM_ANALYSIS_UNKNOWN;
+      $response['spam'] = MOLLOM_ANALYSIS_UNSURE;
       $quality = NULL;
     }
+    // In case a previous spam check was unsure and a CAPTCHA was solved, the
+    // result is supposed to be ham.
+    $captcha_sessions = variable_get('mollom_test_check_captcha_sessions', array());
+    if (!empty($data['session_id']) && !empty($captcha_sessions[$data['session_id']])) {
+      $response['spam'] = MOLLOM_ANALYSIS_HAM;
+    }
   }
 
   // Quality filter.
@@ -145,9 +151,16 @@ function mollom_test_get_captcha($data) {
   variable_set(__FUNCTION__, $storage);
 
   drupal_session_start();
+
+  // Return a HTTPS URL if 'ssl' parameter was passed.
+  $base_url = $GLOBALS['base_url'];
+  if (!empty($data['ssl'])) {
+    $base_url = str_replace('http', 'https', $base_url);
+  }
+
   return array(
     'session_id' => !empty($data['session_id']) ? $data['session_id'] : session_id(),
-    'url' => $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'mollom') . '/images/powered-by-mollom-2.gif',
+    'url' => $base_url . '/' . drupal_get_path('module', 'mollom') . '/images/powered-by-mollom-2.gif',
   );
 }
 
@@ -162,11 +175,16 @@ function mollom_test_check_captcha($data) {
   variable_set(__FUNCTION__, $storage);
 
   if ($data['captcha_result'] == 'correct') {
-    return TRUE;
+    $result = TRUE;
   }
   if ($data['captcha_result'] == 'incorrect') {
-    return FALSE;
+    $result = FALSE;
   }
+  $captcha_sessions = variable_get('mollom_test_check_captcha_sessions', array());
+  $captcha_sessions[$data['session_id']] = $result;
+  variable_set('mollom_test_check_captcha_sessions', $captcha_sessions);
+
+  return $result;
 }
 
 /**
