Source From Here
Preface
Writing unit tests with Python is a joy, especially with the excellent mock library. You can tweak the language and mock almost anything to your will, making testing even the smallest of units very easy. HOWEVER , mocking imports, when a class / module depends on imports which you might not have on your machine, such as windows modules (oei vei) when you are (and you should be) on a nix machine.
Another typical case is when you integrate a module to a big system, which imports THE ENTIRE INTERNETZ in each file. In those cases it’s critical to be able to isolate your class / module by totally disconnecting it from those modules.
Mock to the rescue
Let's check the file structure for demonstration:
- third_party_module.py
- my_module.py
- test_bad_module.py
Launch the testing will get
ImportError:
To fix this, we need to mock the “the internetz” module:
- test_bad_module.py (Updated)
The reason to put all the patches, mocks and imports in the setUp function is that you’d probably reuse them in the same test class on other test methods.
This time to launch the testing will pass:
Preface
Writing unit tests with Python is a joy, especially with the excellent mock library. You can tweak the language and mock almost anything to your will, making testing even the smallest of units very easy. HOWEVER , mocking imports, when a class / module depends on imports which you might not have on your machine, such as windows modules (oei vei) when you are (and you should be) on a nix machine.
Another typical case is when you integrate a module to a big system, which imports THE ENTIRE INTERNETZ in each file. In those cases it’s critical to be able to isolate your class / module by totally disconnecting it from those modules.
Mock to the rescue
Let's check the file structure for demonstration:
- third_party_module.py
- from the.internetz import everything
- import logging
- class World(object):
- """
- what a grand class
- """
- def say(self, msg):
- """
- It speaks!
- """
- everything.log(msg)
- print("Say: {}".format(msg))
- from third_party_module import World
- class MyModule(object):
- """
- My shining class
- """
- def __init__(self):
- """
- Let's instanciate the World (muhaha)
- """
- self.world = World()
- def hello(self):
- """
- My shining method
- """
- self.world.say("hello")
- from unittest import TestCase
- from mock import MagicMock
- from my_module import MyModule
- class TestBadMyModule(TestCase):
- """
- Let's test my module!
- """
- def test_hello_should_say_waitforit_hello(self):
- """
- We want to test that the hello method calls the say function with the string "hello:
- """
- m = MyModule()
- m.world = MagicMock()
- m.hello()
- m.world.say.assert_called_once_with("hello")
To fix this, we need to mock the “the internetz” module:
- test_bad_module.py (Updated)
- from unittest import TestCase
- from mock import MagicMock, patch
- class TestBadMyModule(TestCase):
- """
- Let's test my module!
- """
- def setUp(self):
- """
- It's patching time
- """
- self.internetz_mock = MagicMock()
- self.internetz_mock.the.internetz.everything.log.return_value = True
- modules = {
- 'the': self.internetz_mock,
- 'the.internetz': self.internetz_mock.internetz,
- }
- self.module_patcher = patch.dict('sys.modules', modules)
- self.module_patcher.start()
- from my_module import MyModule
- self.my_module = MyModule
- def tearDown(self):
- """
- Let's clean up
- """
- self.module_patcher.stop()
- def test_hello_should_say_waitforit_hello(self):
- """
- We want to test that the hello method calls the say function with the string "hello:
- """
- m = self.my_module()
- m.world = MagicMock()
- m.hello()
- m.world.say.assert_called_once_with("hello")
This time to launch the testing will pass:
沒有留言:
張貼留言