[TIP] Mocking the .decode(...) method on a string

Michael Foord michael at voidspace.org.uk
Mon Sep 3 05:41:12 PDT 2012


On 29 Aug 2012, at 14:34, Alexander O'Donovan-Jones <Alexander at ccpgames.com> wrote:

> Does anyone know of a way to mock out the .decode(…) method on a string?
> I have a piece of code which essentially does this:
>  
> def CoerceToUnicode(inputString, encoding='cp1252'):
>     try:
>         ret = inputString.decode(encoding)
>     except (UnicodeDecodeError, UnicodeEncodeError):
>         ret = inputString
>     return ret
>  
> However if I try to mock out the str.decode method I get an exception thrown:
>  
> def test_CoerceToUnicode_DecodeException(self):
>     # we mock out the decoding method to throw an exception and check the return
>     with mock.patch('__builtin__.str.decode', side_effect=UnicodeDecodeError):
>         # simple test cases of ascii strings in non-unicode and unicode formats
>         self.assertEqual(CoerceToUnicode('asdf'), 'asdf')
>         self.assertEqual(CoerceToUnicode(u'asdf'), u'asdf')
>  
> raises:
>  
> Traceback (most recent call last):
>   File "c:\depot\eveLauncher\libs\test\test_localization.py", line 220, in test_CoerceToUnicode_DecodeException
>     with mock.patch('__builtin__.str.decode', side_effect=UnicodeDecodeError):
>   File "build\bdist.win32\egg\mock.py", line 1348, in __enter__
>     setattr(self.target, self.attribute, new_attr)
> TypeError: can't set attributes of built-in/extension type 'str'


In general no, you can't patch methods on builtin types. 

You could pass in a mock object instead of a string that will raise the exception when decode is called.

Another option is to change your code to do:

	str.decode(inputString, encoding)

Then you can patch *str* in the namespace it is being used. Better yet do what Ned suggests and actually simulate the conditions that raise the exception.

All the best,

Michael Foord

>  
> Does anyone have experience with mocking out things like this?
> Thanks!
>  
> Alex O’Donovan-Jones
> _______________________________________________
> testing-in-python mailing list
> testing-in-python at lists.idyll.org
> http://lists.idyll.org/listinfo/testing-in-python


--
http://www.voidspace.org.uk/


May you do good and not evil
May you find forgiveness for yourself and forgive others
May you share freely, never taking more than you give.
-- the sqlite blessing 
http://www.sqlite.org/different.html








More information about the testing-in-python mailing list