diff --git a/product/ZMySQLDDA/tests/testDefferedConnection.py b/product/ZMySQLDDA/tests/testDefferedConnection.py
new file mode 100644
index 0000000000000000000000000000000000000000..b47bb1c501c21aa8a2ea8f2c36b4fe609e6f3533
--- /dev/null
+++ b/product/ZMySQLDDA/tests/testDefferedConnection.py
@@ -0,0 +1,196 @@
+##############################################################################
+#
+# Copyright (c) 2006 Nexedi SARL and Contributors. All Rights Reserved.
+#                     Vincent Pelletier <vincent@nexedi.com>
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# This program is Free Software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+##############################################################################
+
+from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
+from AccessControl.SecurityManagement import newSecurityManager
+from _mysql_exceptions import OperationalError
+from Products.ZMySQLDA.db import hosed_connection
+from zLOG import LOG
+
+UNCONNECTED_STATE = 0
+CONNECTED_STATE = 1
+GLOBAL_DB_CONNECTED_FLAG = UNCONNECTED_STATE
+
+def fake_db_store_result(self, *args, **kw):
+  """
+    Mimic store_result to make sure it doesn't fail due to no executed queries.
+  """
+  return
+
+def fake_connection_forceReconnection(self):
+  """
+    Intercept reconnection symptom.
+  """
+  global GLOBAL_DB_CONNECTED_FLAG
+  GLOBAL_DB_CONNECTED_FLAG = CONNECTED_STATE
+  return self.original_forceReconnection()
+
+def fake_db_query(self, *args, **kw):
+  """
+    Mimic a failing query due to a disconnected socket from mysql server.
+  """
+  global GLOBAL_DB_CONNECTED_FLAG
+  if GLOBAL_DB_CONNECTED_FLAG == UNCONNECTED_STATE:
+    raise OperationalError, (hosed_connection[0], 'dummy exception')
+  return self.original_query(*args, **kw)
+
+class TestDefferedConnection(ERP5TypeTestCase):
+  """
+    Test MySQL Deffered Connection
+  """
+
+  def getBusinessTemplateList(self):
+    return tuple()
+
+  def getTitle(self):
+    return "Deffered Connection"
+
+  def setUp(self):
+    ERP5TypeTestCase.setUp(self)
+
+  def afterSetUp(self):
+    self.login()
+
+  def login(self):
+    uf = self.getPortal().acl_users
+    uf._doAddUser('vincent', '', ['Manager'], [])
+    user = uf.getUserById('vincent').__of__(uf)
+    newSecurityManager(None, user)
+
+  def monkeypatchConnection(self, connection):
+    """
+      Apply monkey patch on db and reset connection state to "unconnected".
+      Returns a tuple containing original functions.
+    """
+    mysql_class = connection._getConnection().__class__
+    mysql_class.original_query = mysql_class.query
+    mysql_class.query = fake_db_query
+    connection.__class__.original_forceReconnection = connection.__class__._forceReconnection
+    connection.__class__._forceReconnection = fake_connection_forceReconnection
+    GLOBAL_DB_CONNECTED_FLAG = UNCONNECTED_STATE
+
+  def unmonkeypatchConnection(self, connection):
+    """
+      Revert monkeypatching done on db.
+    """
+    connection.__class__._forceReconnection = connection.__class__.original_forceReconnection
+    delattr(connection.__class__, 'original_forceReconnection')
+    mysql_class = connection._getConnection().__class__
+    mysql_class.query = mysql_class.original_query
+    delattr(mysql_class, 'original_query')
+
+  def getDefferedConnection(self):
+    """
+      Return site's deffered connection object.
+    """
+    deffered = self.getPortal().erp5_sql_deferred_connection
+    deffered_connection = getattr(deffered, '_v_database_connection', None)
+    if getattr(deffered, '_v_database_connection', None) is None:
+      deffered.connect(deffered.connection_string)
+      deffered_connection = getattr(deffered, '_v_database_connection')
+    return deffered_connection
+
+  def test_00_basicReplaceQuery(self):
+    """
+      Check that a basic query succeeds.
+    """
+    connection = self.getDefferedConnection()
+    connection.query('REPLACE INTO `full_text` SET `uid`=0, `SearchableText`="dummy test"')
+    try:
+      get_transaction().commit()
+    except OperationalError:
+      self.fail()
+    except:
+      raise # Make sure the test is known to have failed, even if it's not
+            # the expected execution path.
+
+  def test_01_disconnectsCausesError(self):
+    """
+      Check that a disconnection from mysql causes classical
+      connection.db.query to fail.
+      This makes sure that disconnection-trick monkey patch does work.
+    """
+    connection = self.getDefferedConnection()
+    # Queue a query
+    connection.query('REPLACE INTO `full_text` SET `uid`=0, `SearchableText`="dummy test"')
+    # Replace dynamically the function used to send queries to mysql so it's
+    # dumber than the implemented one.
+    self.monkeypatchConnection(connection)
+    connection._query = connection._getConnection().query
+    try:
+      try:
+        get_transaction().commit()
+      except OperationalError, m:
+        if m[0] not in hosed_connection:
+          raise
+      except:
+        raise # Make sure the test is known to have failed, even if it's not
+              # the expected execution path.
+      else:
+        self.fail()
+    finally:
+      delattr(connection, '_query')
+      self.unmonkeypatchConnection(connection)
+
+  def test_02_disconnectionRobustness(self):
+    """
+      Check that if the connection gets closed before being used the
+      commit can happen without trouble.
+    """
+    connection = self.getDefferedConnection()
+    # Queue a query
+    connection.query('REPLACE INTO `full_text` SET `uid`=0, `SearchableText`="dummy test"')
+    # Artificially cause a connection close.
+    self.monkeypatchConnection(connection)
+    try:
+      try:
+        get_transaction().commit()
+      except OperationalError, m:
+        LOG('TestDefferedConnection', 0, 'OperationalError exception raised: %s' % (m, ))
+        self.fail()
+      except:
+        raise # Make sure the test is known to have failed, even if it's not
+              # the expected execution path.
+    finally:
+      self.unmonkeypatchConnection(connection)
+
+  def test_03_successiveTransactionsIsolation(self):
+    """
+      Check that multiple transactions (one after another) are correctly
+      isolated one from the other.
+    """
+    connection = self.getDefferedConnection()
+    # Queue a query
+    connection.query('REPLACE INTO `full_text` SET `uid`=0, `SearchableText`="dummy test"')
+    self.assertEqual(len(connection._getSQLStringList()), 1)
+    get_transaction().commit()
+    connection.query('REPLACE INTO `full_text` SET `uid`=0, `SearchableText`="dummy test"')
+    self.assertEqual(len(connection._getSQLStringList()), 1)
+
+if __name__ == '__main__':
+  unittest.main()