Trying to mock method in Object gives 'AttributeError'

11,990

I figured out what to do in the end. Bit of a monkey at a typewriter thing, not sure why I have to use "patch" and not "patch.object" or why I need to make Mock() objects first. I just tried every possible pattern from the examples in the docs

Anyway, this works for me

def test_check_url(self):
    url_a = "http://audaxing.wordpress.com"
    dummy_event = self.generate_dummy_auction_event(url_a)
    with patch("sys.stdin") as mock_stdin:
        MaddUrl = Mock()
        Minit = Mock(return_value=None)
        with patch('Foo.crawler.crawlerapp.CrawlerApp.__init__', Minit, create=True):
            with patch('Foo.crawler.crawlerapp.CrawlerApp.addUrl', MaddUrl, create=True):

                ca = Foo.crawler.crawlerapp.CrawlerApp(1)
                mock_stdin.read.return_value = EventDataFrame(1, "TOKEN1", dummy_event.SerializeToString()).to_bytes()
                ca._running = True
                input_thread = threading.Thread(target=ca.inputStreamThread)
                input_thread.start()
                time.sleep(0.5)
                ca._running = False
    MaddUrl.assert_called_with(url_a)
Share:
11,990
Vorsprung
Author by

Vorsprung

Updated on June 04, 2022

Comments

  • Vorsprung
    Vorsprung almost 2 years

    I am trying to test a method in an already existing class. Within inputStreamThread method in the Foo.crawler.crawlerapp.CrawlerApp class the method addUrl is called.

    inputStreamThread reads from stdin and then calls addUrl

    addUrl is also in the CrawlerApp class

    I was hoping to be able to use assert_called_with on a mock addUrl to check that inputStreamThread is doing the right thing and calling addUrl

    Trouble is I cannot get the syntax right for the mock of addUrl within CrawlerApp

    I used an example straight out of the mock docs but get the error shown below

    As you can see I am also mocking stdin to be able to present test data on it

    My question is, what code do I use to carry out this sort of test and not get the error shown?

    import Foo.crawler.crawlerapp
    from unittest import TestCase
    from mock import patch, Mock
    from mephistopheles.messageformat import EventDataFrame
    from mephistopheles.messageformat.types import adservers as pbufs
    import time
    import sys
    
    
    class testDeserial(TestCase):
    
        def generate_dummy_auction_event(self,url):
            adunitinfo = pbufs.AdUnitInfo(index_on_page=0, url=url)
            geoloc = pbufs.GeoLocation(country="DE", region="low")
            userinfo = pbufs.UserInfo(user_hash=1,
                                      ip_octets=1,
                                      geolocation=geoloc,
                                      language="en")
            auctioninfo = pbufs.AuctionInfo(timestamp=int(time.time()),
                                            user=userinfo,
                                            ad_unit=adunitinfo)
            return auctioninfo
    
        def setUp(self):
            pass
    
        @patch.object(Foo.crawler.crawlerapp.CrawlerApp,'addUrl')
        def test_check_url(self, MaddUrl):
            url_a = "http://audaxing.wordpress.com"
            dummy_event = self.generate_dummy_auction_event(url_a)
            with patch("sys.stdin") as mock_stdin:
                mock_stdin.read.return_value = dummy_event
                ca._running = True
                input_thread = threading.Thread(target=self.inputStreamThread)
                input_thread.start()
                time.sleep(0.5)
                ca._running = False
            MaddUrl.assert_called_with(url_a)
    

    The test run output....

    $ bin/tests --tests-pattern=test_deserialize
    Test-module import failures:
    
    Module: Foo.crawler.tests.test_deserialize
    
    Traceback (most recent call last):
      File "/home/jamie/svn/Foo/crawler.buildout/trunk/src/Foo.crawler/Foo/crawler/tests/test_deserialize.py", line 11, in <module>
        class testDeserial(TestCase):
      File "/home/jamie/svn/Foo/crawler.buildout/trunk/src/Foo.crawler/Foo/crawler/tests/test_deserialize.py", line 28, in testDeserial
        @patch.object(Foo.crawler.crawlerapp.CrawlerApp,'addUrl')
    AttributeError: 'function' object has no attribute 'object'
    
    
    
    Test-modules with import problems:
      Foo.crawler.tests.test_deserialize
    Total: 0 tests, 0 failures, 0 errors in 0.000 seconds.