[Tutor] Mocking with "mock" in unit testing
James Chapman
james at uplinkzero.com
Fri Jan 17 12:18:48 CET 2014
Erm...?
CPython yeah.
If I rename "pinger.py" to "tutor.py" and change the unittest it runs fine.
Why?
-------------------------
import mock
import unittest
import tutor
class Test_Pinger(unittest.TestCase):
def test_ping_host_succeeds(self):
pinger = tutor.Pinger()
with mock.patch("tutor.subprocess") as subprocess:
subprocess.Popen.return_value.returncode = 0
pinger.ping_host('localhost')
subprocess.Popen.assert_called_once_with(['ping','localhost'],
shell=True)
def test_ping_host_fails_and_throws_exception(self):
pinger = tutor.Pinger()
with mock.patch('tutor.subprocess') as subprocess:
subprocess.Popen.return_value.returncode = 1
self.assertRaises(Exception, pinger.ping_host, 'localhost')
if __name__ == '__main__':
unittest.main()
-------------------------
--
James
On 17 January 2014 10:50, eryksun <eryksun at gmail.com> wrote:
> 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)
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140117/1603996d/attachment.html>
More information about the Tutor
mailing list