[Tutor] Mocking with "mock" in unit testing
eryksun
eryksun at gmail.com
Fri Jan 17 11:50:39 CET 2014
On Fri, Jan 17, 2014 at 4:58 AM, James Chapman <james at uplinkzero.com> wrote:
> import mock
> import unittest
> import pinger
>
> class Test_Pinger(unittest.TestCase):
>
> def test_ping_host_succeeds(self):
> pinger = pinger.Pinger()
Are you using CPython? That raises an UnboundLocalError. Take a look
at the CPython bytecode:
def test(self):
pinger = pinger.Pinger()
>>> dis.dis(test)
2 0 LOAD_FAST 1 (pinger)
3 LOAD_ATTR 0 (Pinger)
6 CALL_FUNCTION 0
9 STORE_FAST 1 (pinger)
12 LOAD_CONST 0 (None)
15 RETURN_VALUE
Notice LOAD_FAST(1), where fast local 1 is the local variable
`pinger`. The value isn't assigned yet, and LOAD_FAST doesn't search
globals and builtins. You need a unique name for the instance, such as
`test_pinger`. Then the compiler knows to use LOAD_GLOBAL:
def test(self):
test_pinger = pinger.Pinger()
>>> dis.dis(test)
2 0 LOAD_GLOBAL 0 (pinger)
3 LOAD_ATTR 1 (Pinger)
6 CALL_FUNCTION 0
9 STORE_FAST 1 (test_pinger)
12 LOAD_CONST 0 (None)
15 RETURN_VALUE
Here's a version using a decorator instead:
@mock.patch('pinger.subprocess')
def test_ping_host_succeeds(self, subprocess):
subprocess.Popen.return_value.returncode = 0
test_pinger = pinger.Pinger()
test_pinger.ping_host('localhost')
subprocess.Popen.assert_called_once_with(['ping','localhost'],
shell=True)
More information about the Tutor
mailing list