[Tutor] Mocking with "mock" in unit testing

eryksun eryksun at gmail.com
Fri Jan 17 14:35:04 CET 2014


On Fri, Jan 17, 2014 at 6:23 AM, Steven D'Aprano <steve at pearwood.info> wrote:
> On Fri, Jan 17, 2014 at 09:58:06AM +0000, James Chapman wrote:
>
>> import subprocess
>>  class Pinger(object):
>
> There is your first SyntaxError, a stray space ahead of the "class"
> keyword.

The rich text version is correct (and colorful), but a non-breaking
space ended up on a line in between the <span> elements in the <pre>
block:

    <span s=
    tyle=3D"color:rgb(220,20,60)">subprocess</span>
    =C2=A0
    <span style=3D"color:rgb(255,119,0);font-weight:bold">class</span>

The automated conversion to plain text removed the line break.


> Better to do something like:
>
>         cmd_args = ["ping", host_to_ping]
>
> assuming that you know that host_to_ping is only a single word.

If it isn't a single word, then use `shlex.split`, as I previously suggested.


> Why shell=True?
....
> and also warns that shell=True can be a security hazard. Do you have a
> good reason for using it?

I already asked this and got the response "this question was just about mock".


>> 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.

This is also fine in the rich text version. BTW, the botched plain
text conversion is missing line breaks, not commas.


>>     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.

As you say, for a function. Optimized code requires the name to be
bound locally, else it raises UnboundLocalError. The unoptimized code
of a class body, on the other hand, can load a name from globals or
builtins and then store the same name to locals.

    >>> x = 'global x'
    >>> class C(object):
    ...     x = x + ", but now local"
    ...     print x
    ...
    global x, but now local
    >>> x
    'global x'


More information about the Tutor mailing list