How to mock stompest send, and connect methods
Question: I am writing a log handler for `ActiveMQ`. I have one class, `Messenger`, to
publish a message to `ActiveMQ`. Also, I added class `Handler` to handle this
and `get_logger` to get this logger.

    
    
    import json
    import logging
    
    from stompest.config import StompConfig
    from stompest.sync import Stomp
    
    class Messanger(object):
        def __init__(self, uri):
            self.cfg = StompConfig(uri)
    
        def publish(self, queue, data):
            data = json.dumps(data)
            client = Stomp(self.cfg)
            client.connect()
    
            try:
                client.send(queue, data)
            except Exception, exc:
                print "Error: ", exc
            client.disconnect()
    
    class Handler(logging.Handler):
        def __init__(self, amq_uri, out_queue):
            logging.Handler.__init__(self)
            self.queue = queue
            self.uri = uri
    
        def emit(self, record):
            msg = self.format(record)
            messanger = Messanger(self.uri)
            messanger.send(self.queue, msg)
    
    
    
    def get_logger(uri, queue):
        logger = logging.getLogger('testlogger')
        logger.addHandler(Handler(uri, queue))
    
        return logger
    

I have written a UT for this.

    
    
    from unittest import TestCase
    from mock import patch, Mock
    
    from my_package import get_logger 
    
    class TestHandler(TestCase):
        @patch('stompest.sync.client.Stomp')
        def test_activemq_handler(self, mock_stomp):
            URI = "tcp://localhost:61613"
            QUEUE = "/queue/logger_queue"
    
            mock_stomp.connect = Mock(return_value=1)
            mock_stomp.send = Mock(return_value=2)
    
            data = "This is test logging"
    
            LOG = get_logger(URI, QUEUE)
            LOG.error(data)
    

But still it goes to the original send method and tries to connect to the
server.

    
    
    Traceback (most recent call last):
      File ".my_package/venv/lib/python2.7/site-packages/mock/mock.py", line 1305, in patched
        return func(*args, **keywargs)
      File "./my_package/tests/test_activemq_handler.py", line 23, in test_activemq_handler
        LOG.error(data)
      File "/System/Library/Python.framework/Versions/2.7/lib/python2.7/logging/__init__.py", line 1191, in error
        self._log(ERROR, msg, args, **kwargs)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/logging/__init__.py", line 1284, in _log
        self.handle(record)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/logging/__init__.py", line 1294, in handle
        self.callHandlers(record)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/logging/__init__.py", line 1334, in callHandlers
        hdlr.handle(record)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/logging/__init__.py", line 757, in handle
        self.emit(record)
      File "./my_package/__init__.py", line 28, in emit
        messanger.send(self.queue, msg)
      File "./my_package/clients/stomp_messanger.py", line 41, in send
        client.connect()
      File "./my_package/venv/lib/python2.7/site-packages/stompest/sync/client.py", line 85, in connect
        for (broker, connectDelay) in self._failover:
      File "./my_package/venv/lib/python2.7/site-packages/stompest/protocol/failover.py", line 48, in __iter__
        yield broker, self._delay()
      File "./my_package/venv/lib/python2.7/site-packages/stompest/protocol/failover.py", line 66, in _delay
        raise StompConnectTimeout('Reconnect timeout: %d attempts' % self._maxReconnectAttempts)
    StompConnectTimeout: Reconnect timeout: 0 attempts
    

How can I mock this?


Answer: > The basic principle is that you patch where an object is looked up, which is
> not necessarily the same place as where it is defined.

You are adding the patch to the wrong place. The `Messenger` class module
imports `Stomp` from `stompest.sync` before the tests run, and that's why your
patching has no effect. You should patch the reference to `Stomp` in your
module.

    
    
    from unittest import TestCase
    from mock import patch, Mock
    
    from my_package import get_logger 
    
    class TestHandler(TestCase):
        @patch('path.to.your.Messenger_class_module.Stomp') #path to your module
        def test_activemq_handler(self, mock_stomp):
            URI = "tcp://localhost:61613"
            QUEUE = "/queue/logger_queue"
    
            ...
    

[This](http://www.voidspace.org.uk/python/mock/patch.html#where-to-patch) will
help if you need further clarification on why this is happening.

