One is the proxy module. Basically you define a module to hide all of the OS-specific imports behind, and do a conditional import in that module. So instead of having code like this:
import win32api win32api.GetLogicalDriveStrings()you do
import windows_imports windows_imports.win32api.GetLogicalDriveStrings()and then in windows_imports/__init__.py:
import platform if platform.system() == "Windows": import win32api import winerror import wmiThen inside your tests you need to create stubs to replace your API calls, e.g. for windows_imports.win32api.GetLogicalDriveStrings. Theoretically this should be fairly straightforward, but when I started down this path it got fairly complicated and I struggled to make it work. In the end I gave up and settled on the second approach, as below.
The second approach, described here, is to delay the import of the OS specific code in your tests until after you modify sys.modules to stub out all the OS-specific modules. This has the distinct advantage of leaving your production code untouched, and having all the complexity in your test code. Using the mock library makes this much easier. Below is an example of mocking out a WMI call made from python.
import mock import test_fixture import unittest class WindowsTests(unittest.TestCase): def setUp(self): self.wmimock = mock.MagicMock() self.win32com = mock.MagicMock() self.win32com.client = mock.MagicMock() modules = { "_winreg": mock.MagicMock(), "pythoncom": mock.MagicMock(), "pywintypes": mock.MagicMock(), "win32api": mock.MagicMock(), "win32com": self.win32com, "win32com.client": self.win32com.client, "win32file": mock.MagicMock(), "win32service": mock.MagicMock(), "win32serviceutil": mock.MagicMock(), "winerror": mock.MagicMock(), "wmi": self.wmimock } self.module_patcher = mock.patch.dict("sys.modules", modules) self.module_patcher.start() # Now we're ready to do the import from myrepo.actions import windows self.windows = windows def tearDown(self): self.module_patcher.stop() def testEnumerateInterfaces(self): # Stub out wmi.WMI().Win32_NetworkAdapterConfiguration(IPEnabled=1) wmi_object = self.wmimock.WMI.return_value wmi_object.Win32_NetworkAdapterConfiguration.return_value = [ test_fixture.WMIWin32NetworkAdapterConfigurationMockResults()] enumif = self.windows.EnumerateInterfaces() interface_dict_list = list(enumif.RunWMIQuery())
No comments:
Post a Comment