Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mock - patch class method to raise exception

Here's a generalized example of the code I'm trying to test using mock. I get an AttributeError.

Here's __init__.py:

import logging
log = logging.getLogger(__name__)

class SomeError(Exception):
    pass

class Stuff(object):
    # stub

    def method_a(self):
        try:
            stuff = self.method_b()
        except SomeError, e:
            log.error(e)
            # show a user friendly error message
            return 'no ponies'
        return 'omg ponies'

    def method_b(self):
        # can raise SomeError
        return ''

In tests.py I have something like this:

import mock
import unittest

from package.errors import SomeError
from mypackage import Stuff

some_error_mock = mock.Mock()
some_error_mock.side_effect = SomeError

class MyTest(unittest.TestCase):

    @mock.patch.object('Stuff', 'method_b', some_error_mock)
    def test_some_error(self):
        # assert that method_a handles SomeError correctly
        mystuff = Stuff()
        a = mystuff.method_a()
        self.assertTrue(a == 'no ponies')

When running the test, mock raises AttributeError saying: "Stuff does not have the attribute 'method_b'"

What am I doing wrong here?

like image 759
hannson Avatar asked Jan 24 '14 12:01

hannson


People also ask

How do you raise an exception in Python mock?

Raising exceptions with mocks A useful attribute is side_effect . If you set this to an exception class or instance then the exception will be raised when the mock is called. >>> mock = Mock(side_effect=Exception('Boom!

What is mock and patch?

mock provides a powerful mechanism for mocking objects, called patch() , which looks up an object in a given module and replaces that object with a Mock . Usually, you use patch() as a decorator or a context manager to provide a scope in which you will mock the target object.

Should I use mock MagicMock?

Mock vs. MagicMock is a subclass of Mock . It contains all magic methods pre-created and ready to use (e.g. __str__ , __len__ , etc.). Therefore, you should use MagicMock when you need magic methods, and Mock if you don't need them.

What is mock MagicMock?

Accessing the same attribute will always return the same mock. Mocks record how you use them, allowing you to make assertions about what your code has done to them. MagicMock is a subclass of Mock with all the magic methods pre-created and ready to use.


1 Answers

The decorator first argument should be the class of the object, you mistakenly used a string of the name of the class

@mock.patch.object('Stuff', 'method_b', some_error_mock)

should become

@mock.patch.object(Stuff, 'method_b', some_error_mock)

http://docs.python.org/dev/library/unittest.mock#patch-object

like image 135
Matteo Scotuzzi Avatar answered Oct 12 '22 00:10

Matteo Scotuzzi