[Tutor] Mocking with "mock" in unit testing

James Chapman james at uplinkzero.com
Fri Jan 17 12:39:06 CET 2014


Ah of course!
pinger = pinger.Pinger() .... I should have noticed that myself.  (I
renamed the file to pinger.py after establishing it all worked and then
didn't re-run).
ping = pinger.Pinger() works fine.

As for the syntax errors, those will be copy paste / different email client
errors.

--
James


On 17 January 2014 11:23, Steven D'Aprano <steve at pearwood.info> wrote:

> On Fri, Jan 17, 2014 at 09:58:06AM +0000, James Chapman wrote:
>
> > As this question was just about mock and not really dealing with the bad
> > return code or exception handling or raising my final working example
> looks
> > like this:
>
> Your final *working* example? I don't think so. I can see at least two
> syntax errors, and a programming error.
>
> A word to the wise: code isn't working until you've actually seen it
> work :-)
>
>
>
> > pinger.py
> >
> > ----------------------------
> >
> > import subprocess
> >  class Pinger(object):
>
> There is your first SyntaxError, a stray space ahead of the "class"
> keyword.
>
>
> >     def ping_host(self, host_to_ping):
> >         cmd_string = 'ping %s' % (host_to_ping)
> >         cmd_args = cmd_string.split()
>
> This is not a programming error, but it is wasteful. First you join two
> strings: "ping", and the host. Then, having glued them together, you
> split them apart exactly where you glued them.
>
> Better to do something like:
>
>         cmd_args = ["ping", host_to_ping]
>
> assuming that you know that host_to_ping is only a single word.
>
>
> >         proc = subprocess.Popen(cmd_args, shell=True)
>
> Why shell=True?
>
> The documentation for subprocess.Popen says:
>
>     The shell argument (which defaults to False) specifies whether to
>     use the shell as the program to execute. If shell is True, it is
>     recommended to pass args as a string rather than as a sequence.
>
> and also warns that shell=True can be a security hazard. Do you have a
> good reason for using it?
>
> http://docs.python.org/2/library/subprocess.html
>
>
>
> >         proc.wait()
> >         if proc.returncode != 0:
> >             raise Exception('Error code was: %d' % (proc.returncode))
> >
> >  if __name__ == '__main__':
> >     PINGER = Pinger()
> >     PINGER.ping_host('localhost')
> >
> > ----------------------------
> >
> >
> >
> > test_pinger.py
> >
> > ----------------------------
> >
> > import mockimport unittestimport pinger
> >  class Test_Pinger(unittest.TestCase):
>
> And here you have two more SyntaxErrors: missing commas between
> arguments to import, and a stray space before the "class" again.
>
>
> >     def test_ping_host_succeeds(self):
> >         pinger = pinger.Pinger()
>
> And here is your programming error. Unlike some programming languages
> (Lua, I think) in Python you cannot use the same name to refer to both a
> global variable and a local variable inside the same function. In
> Python, either the variable is treated as a global, or as a local, but
> not both.
>
> The rules Python uses to decide are:
>
> * if you declare a name "global" inside the function, then it is
>   treated as global inside that function;
>
> * otherwise, if you assign a value to the name *anywhere* inside
>   the function, it is treated as local;
>
> * otherwise it is global.
>
> So in your example, you assign a value to the name "pinger", so it is
> treated as local. The offending line of code looks like this:
>
>     pinger = pinger.Pinger()
>
> Your *intention* is to look up the global "pinger", which is a module,
> then create a pinger.Pinger() instance, then assign it to the local
> variable "pinger". But that's not what Python does. Instead, it tries to
> look up a local variable "pinger", finds it doesn't have one, and raises
> an UnboundLocalError exception.
>
> I recommend you change the name of the local variable "pinger" to
> something else, so it no longer clashes with the "pinger" module name.
>
>
> Hope this is of help to you,
>
>
>
> --
> Steven
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20140117/8561f715/attachment-0001.html>


More information about the Tutor mailing list