Index: main/waeup.kofa/trunk/src/waeup/kofa/utils/tests/test_batching.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/utils/tests/test_batching.py	(revision 7819)
+++ main/waeup.kofa/trunk/src/waeup/kofa/utils/tests/test_batching.py	(revision 7857)
@@ -21,4 +21,5 @@
 import shutil
 import tempfile
+import unittest
 from zope import schema
 from zope.component import provideUtility
@@ -26,7 +27,9 @@
 from zope.component.hooks import clearSite
 from zope.component.interfaces import IFactory
-from zope.interface import Interface, implements
+from zope.interface import Interface, implements, verify
 from waeup.kofa.app import University
+from waeup.kofa.interfaces import ICSVExporter
 from waeup.kofa.testing import FunctionalLayer, FunctionalTestCase
+from waeup.kofa.utils.batching import ExporterBase
 
 optionflags = (
@@ -231,4 +234,95 @@
         return
 
-#def test_suite():
-#    return unittest.TestSuite()
+class ExporterBaseTests(unittest.TestCase):
+
+    def setUp(self):
+        self.workdir = tempfile.mkdtemp()
+        self.workfile = os.path.join(self.workdir, 'testfile.csv')
+        return
+
+    def tearDown(self):
+        shutil.rmtree(self.workdir)
+        return
+
+    def test_iface(self):
+        # ExporterBase really implements the promised interface.
+        obj = ExporterBase()
+        verify.verifyClass(ICSVExporter, ExporterBase)
+        verify.verifyObject(ICSVExporter, obj)
+        return
+
+    def test_unimplemented(self):
+        # make sure the not implemented methods signal that.
+        exporter = ExporterBase()
+        self.assertRaises(NotImplementedError, exporter.export_all, None)
+        self.assertRaises(NotImplementedError, exporter.export, None)
+        return
+
+    def test_mangle_value(self):
+        # some basic types are mangled correctly
+        exporter = ExporterBase()
+        result1 = exporter.mangle_value(True, 'foo')
+        result2 = exporter.mangle_value(False, 'foo')
+        result3 = exporter.mangle_value('string', 'foo')
+        result4 = exporter.mangle_value(u'string', 'foo')
+        result5 = exporter.mangle_value(None, 'foo')
+        self.assertEqual(
+            (result1, result2, result3, result4, result5),
+            ('1', '0', u'string', u'string', ''))
+        self.assertEqual(type(result3), type('string'))
+        self.assertEqual(type(result4), type('string'))
+        return
+
+    def test_get_csv_writer(self):
+        # we can get a CSV writer to a memory file
+        exporter = ExporterBase()
+        writer, outfile = exporter.get_csv_writer()
+        writer.writerow(dict(code='A', title='B', title_prefix='C'))
+        outfile.seek(0)
+        self.assertEqual(
+            outfile.read(),
+            'code,title,title_prefix\r\nA,B,C\r\n')
+        return
+
+    def test_get_csv_writer_with_file(self):
+        # we can get CSV writer that writes to a real file
+        exporter = ExporterBase()
+        writer, outfile = exporter.get_csv_writer(filepath=self.workfile)
+        writer.writerow(dict(code='A', title='B', title_prefix='C'))
+        outfile.close()
+        resultfile = open(self.workfile, 'rb')
+        self.assertEqual(
+            resultfile.read(),
+            'code,title,title_prefix\r\nA,B,C\r\n')
+        return
+
+    def test_write_item(self):
+        # we can write items to opened exporter files.
+        exporter = ExporterBase()
+        writer, outfile = exporter.get_csv_writer()
+        class Sample(object):
+            code = 'A'
+            title = u'B'
+            title_prefix = True
+        exporter.write_item(Sample(), writer)
+        outfile.seek(0)
+        self.assertEqual(
+            outfile.read(),
+            'code,title,title_prefix\r\nA,B,1\r\n')
+        return
+
+    def test_close_outfile(self):
+        # exporters can help to close outfiles.
+        exporter = ExporterBase()
+        writer, outfile = exporter.get_csv_writer()
+        result = exporter.close_outfile(None, outfile)
+        self.assertEqual(result, 'code,title,title_prefix\r\n')
+        return
+
+    def test_close_outfile(self):
+        # we can also close outfiles in real files.
+        exporter = ExporterBase()
+        writer, outfile = exporter.get_csv_writer(filepath=self.workfile)
+        result = exporter.close_outfile(self.workfile, outfile)
+        self.assertEqual(result, None)
+        return
