[tor-commits] [stem/master] Using mock for tutorial unit tests

atagar at torproject.org atagar at torproject.org
Thu Jun 13 16:50:53 UTC 2013


commit 9c0f1d37c0febbaacd2b6b73a2d094d3583869ba
Author: Damian Johnson <atagar at torproject.org>
Date:   Sun Jun 9 18:20:49 2013 -0700

    Using mock for tutorial unit tests
    
    The unit tests for our tutorials are some of the ugliest we have since they
    make heavy use of mocks. Hence a good next step for mock.
    
    The mock module makes the controller mocking considerably nicer. That said,
    mock's open() mocking is crap. Their mock_open() docs...
    
    http://www.voidspace.org.uk/python/mock/helpers.html#mock.mock_open
    
    Tripped me up for well over an hour because their examples are hardcoded for
    the __main__ namespace (so it works when I do it in an interpretor, but not the
    tests). Even with that fixed the mock object it returns is buggy as hell (it's
    documented as supporting readlines() but that's a lie). They'd get a lot more
    mileage if they used an io.BytesIO instead.
---
 test/unit/tutorial.py |   98 +++++++++++++++----------------------------------
 1 file changed, 30 insertions(+), 68 deletions(-)

diff --git a/test/unit/tutorial.py b/test/unit/tutorial.py
index 14050cf..0f66a83 100644
--- a/test/unit/tutorial.py
+++ b/test/unit/tutorial.py
@@ -6,12 +6,11 @@ import io
 import StringIO
 import unittest
 
-from mock import patch
+from mock import Mock, patch
 
 from stem.control import Controller
 from stem.descriptor.reader import DescriptorReader
 from stem.descriptor.server_descriptor import RelayDescriptor
-from stem.prereq import is_python_3
 from test import mocking
 
 MIRROR_MIRROR_OUTPUT = """\
@@ -22,14 +21,9 @@ MIRROR_MIRROR_OUTPUT = """\
 
 
 class TestTutorial(unittest.TestCase):
-  def setUp(self):
-    mocking.mock_method(RelayDescriptor, '_verify_digest', mocking.no_op())
-
-  def tearDown(self):
-    mocking.revert_mocking()
-
   @patch('sys.stdout', new_callable = StringIO.StringIO)
-  def test_the_little_relay_that_could(self, stdout_mock):
+  @patch('stem.control.Controller.from_port', spec = Controller)
+  def test_the_little_relay_that_could(self, from_port_mock, stdout_mock):
     def tutorial_example():
       from stem.control import Controller
 
@@ -41,26 +35,18 @@ class TestTutorial(unittest.TestCase):
 
         print "My Tor relay has read %s bytes and written %s." % (bytes_read, bytes_written)
 
-    controller = mocking.get_object(Controller, {
-      'authenticate': mocking.no_op(),
-      'close': mocking.no_op(),
-      'get_info': mocking.return_for_args({
-        ('traffic/read',): '33406',
-        ('traffic/written',): '29649',
-      }, is_method = True),
-    })
-
-    mocking.mock(
-      Controller.from_port, mocking.return_value(controller),
-      target_module = Controller,
-      is_static = True,
-    )
+    controller = from_port_mock().__enter__()
+    controller.get_info.side_effect = lambda arg: {
+      'traffic/read': '33406',
+      'traffic/written': '29649',
+    }[arg]
 
     tutorial_example()
     self.assertEqual("My Tor relay has read 33406 bytes and written 29649.\n", stdout_mock.getvalue())
 
   @patch('sys.stdout', new_callable = StringIO.StringIO)
-  def test_mirror_mirror_on_the_wall_1(self, stdout_mock):
+  @patch('stem.control.Controller.from_port', spec = Controller)
+  def test_mirror_mirror_on_the_wall_1(self, from_port_mock, stdout_mock):
     def tutorial_example():
       from stem.control import Controller
 
@@ -70,25 +56,15 @@ class TestTutorial(unittest.TestCase):
         for desc in controller.get_network_statuses():
           print "found relay %s (%s)" % (desc.nickname, desc.fingerprint)
 
-    controller = mocking.get_object(Controller, {
-      'authenticate': mocking.no_op(),
-      'close': mocking.no_op(),
-      'get_network_statuses': mocking.return_value(
-        [mocking.get_router_status_entry_v2()],
-      ),
-    })
-
-    mocking.mock(
-      Controller.from_port, mocking.return_value(controller),
-      target_module = Controller,
-      is_static = True,
-    )
+    controller = from_port_mock().__enter__()
+    controller.get_network_statuses.return_value = [mocking.get_router_status_entry_v2()]
 
     tutorial_example()
     self.assertEqual("found relay caerSidi (A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n", stdout_mock.getvalue())
 
   @patch('sys.stdout', new_callable = StringIO.StringIO)
-  def test_mirror_mirror_on_the_wall_2(self, stdout_mock):
+  @patch('%s.open' % __name__, create = True)
+  def test_mirror_mirror_on_the_wall_2(self, open_mock, stdout_mock):
     def tutorial_example():
       from stem.descriptor import parse_file
 
@@ -100,20 +76,16 @@ class TestTutorial(unittest.TestCase):
       content = True,
     ))
 
-    mocking.support_with(test_file)
     test_file.name = "/home/atagar/.tor/cached-consensus"
-
-    if is_python_3():
-      import builtins
-      mocking.mock(open, mocking.return_value(test_file), target_module = builtins)
-    else:
-      mocking.mock(open, mocking.return_value(test_file))
+    open_mock.return_value = test_file
 
     tutorial_example()
     self.assertEqual("found relay caerSidi (A7569A83B5706AB1B1A9CB52EFF7D2D32E4553EB)\n", stdout_mock.getvalue())
 
   @patch('sys.stdout', new_callable = StringIO.StringIO)
-  def test_mirror_mirror_on_the_wall_3(self, stdout_mock):
+  @patch('stem.descriptor.reader.DescriptorReader', spec = DescriptorReader)
+  @patch('stem.descriptor.server_descriptor.RelayDescriptor._verify_digest', Mock())
+  def test_mirror_mirror_on_the_wall_3(self, reader_mock, stdout_mock):
     def tutorial_example():
       from stem.descriptor.reader import DescriptorReader
 
@@ -121,17 +93,16 @@ class TestTutorial(unittest.TestCase):
         for desc in reader:
           print "found relay %s (%s)" % (desc.nickname, desc.fingerprint)
 
-    mocking.mock(
-      DescriptorReader.__iter__,
-      mocking.return_value(iter([mocking.get_relay_server_descriptor()])),
-      target_module = DescriptorReader
-    )
+    reader = reader_mock().__enter__()
+    reader.__iter__.return_value = iter([mocking.get_relay_server_descriptor()])
 
     tutorial_example()
     self.assertEqual("found relay caerSidi (None)\n", stdout_mock.getvalue())
 
   @patch('sys.stdout', new_callable = StringIO.StringIO)
-  def test_mirror_mirror_on_the_wall_4(self, stdout_mock):
+  @patch('stem.control.Controller.from_port', spec = Controller)
+  @patch('stem.descriptor.server_descriptor.RelayDescriptor._verify_digest', Mock())
+  def test_mirror_mirror_on_the_wall_4(self, from_port_mock, stdout_mock):
     def tutorial_example():
       from stem.control import Controller
       from stem.util import str_tools
@@ -169,22 +140,13 @@ class TestTutorial(unittest.TestCase):
     exit_descriptor = mocking.sign_descriptor_content(exit_descriptor)
     exit_descriptor = RelayDescriptor(exit_descriptor)
 
-    controller = mocking.get_object(Controller, {
-      'authenticate': mocking.no_op(),
-      'close': mocking.no_op(),
-      'get_server_descriptors': mocking.return_value([
-        exit_descriptor,
-        mocking.get_relay_server_descriptor(),  # non-exit
-        exit_descriptor,
-        exit_descriptor,
-      ])
-    })
-
-    mocking.mock(
-      Controller.from_port, mocking.return_value(controller),
-      target_module = Controller,
-      is_static = True,
-    )
+    controller = from_port_mock().__enter__()
+    controller.get_server_descriptors.return_value = [
+      exit_descriptor,
+      mocking.get_relay_server_descriptor(),  # non-exit
+      exit_descriptor,
+      exit_descriptor,
+    ]
 
     tutorial_example()
     self.assertEqual(MIRROR_MIRROR_OUTPUT, stdout_mock.getvalue())





More information about the tor-commits mailing list