uber/doubles

cannot raise exceptions that take arguments

mehulkar opened this issue · 2 comments

I'm attempting to mock a subprocess.CalledProcessError exception, but subprocess.CalledProcessException needs to be raised with some arguments:

>>> import subprocess
>>> raise subprocess.CalledProcessError
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() takes at least 3 arguments (1 given)

so when I use .and_raise(subprocess.CalledProcessError), I get a TypeError: __init__() takes at least 3 arguments (1 given) (coming from the ProxyMethod __call__ method.

I am not sure how to pass in arguments to be applied later with .and_raise.

I also tried to create an allowance for the CalledProcessError itself, but I get a TypeError, because python cannot raise a ProxyMethod:

>>> from doubles import allow
>>> allow(subprocess).CalledProcessError
<doubles.allowance.Allowance object at 0x107205110>
>>> allow(subprocess).check_output.and_raise(subprocess.CalledProcessError)
<doubles.allowance.Allowance object at 0x107205290>
>>> subprocess.check_output()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mehulkar/dev/aptools/ique/tmp/env/lib/python2.7/site-packages/doubles/proxy_method.py", line 79, in __call__
    return expectation.return_value(*args, **kwargs)
  File "/Users/mehulkar/dev/aptools/ique/tmp/env/lib/python2.7/site-packages/doubles/allowance.py", line 246, in return_value
    return self._return_value(*args, **kwargs)
  File "/Users/mehulkar/dev/aptools/ique/tmp/env/lib/python2.7/site-packages/doubles/allowance.py", line 71, in proxy_exception
    raise exception
TypeError: exceptions must be old-style classes or derived from BaseException, not ProxyMethod

Is there a better way to do mock an exception on subprocess.check_output?

I'm using Python 2.7

I think if you instantiate the error yourself (with the correct args), you should be ok:

Example:

import doubles
class Foo(object):
   def throw_me(self):
       return "foo"

f = Foo()
expect(f).throw_me.and_raise(subprocess.CalledProcessError(1,2))
f.throw_me()

hah. that was simpler than expected. Thank you!