试图在Object中模拟方法给出'AttributeError'

时间:2013-04-10 14:17:57

标签: python unit-testing python-2.7 mocking

我正在尝试在已有的类中测试方法。在inputStreamThread类的Foo.crawler.crawlerapp.CrawlerApp方法中,调用方法addUrl

inputStreamThread从stdin读取,然后调用addUrl

addUrl也位于CrawlerApp

我希望能够在模拟assert_called_with上使用addUrl检查inputStreamThread是否正在做正确的事并致电addUrl

麻烦是我无法在addUrl

中模拟CrawlerApp的语法

我直接使用了模拟文档中的示例,但得到了下面显示的错误

正如你所看到的,我也在嘲笑stdin能够在其上呈现测试数据

我的问题是,我使用什么代码来执行此类测试但未显示错误?

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)

测试运行输出....

$ 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.

2 个答案:

答案 0 :(得分:1)

我弄清楚到底要做什么。有点像打字机的猴子,不知道为什么我必须使用“补丁”而不是“patch.object”或为什么我需要先制作Mock()对象。我刚刚从文档中的示例中尝试了所有可能的模式

无论如何,这对我有用

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)

答案 1 :(得分:0)

我会说以下内容:

@patch.object... #1
def test_check... #2

相当于

def test_check... #2

test_check.object = ... #1

并且无法为函数对象分配新属性。