2014-02-26 47 views
1

我有以下一段代碼UT,這使我陷入困境:如何模擬MongoClient for python單元測試?

def initialize(): 
    try : 
     self.client = MongoClient("127.0.0.1", 27017) 
     self.conn = self.client["DB_NAME"] 
    except Exception: 
     print "Except in initialize!" 
     return False 
    return True 

我寫下面的測試案例,以補足上述的功能,希望能得到返回值「真」:

def mock_mongodb_mongoclient_init(self, para1, para2): 
    pass 

def mock_mongodb_mongoclient_getitem(self, name): 
    return {"DB_NAME":"Something"} 

def test_mongodb_initialize_true(self): 
    self.patcher1 = patch('pymongo.MongoClient.__init__', new=self.mock_mongodb_mongoclient_init) 
    self.patcher2 = patch('pymongo.MongoClient.__getitem__', new=self.mock_mongodb_mongoclient_getitem) 
    self.patcher1.start() 
    self.patcher2.start() 
    self.assertEqual(initialize(), True) 
    self.patcher1.stop() 
    self.patcher2.stop() 

但是這從來不行!它總是報告「初始化異常!」!並返回「假」。

我怎麼能UT這個MongoClient,並使該函數返回「真」?

+0

包括''在traceback.print_exc()你除了塊以查看更多信息關於失敗。 – pbacterio

+0

當回溯異常時,打印如下內容:return database.Database(self,name) 文件「C:\ Python27 \ lib \ site-packages \ pymongo-2.6.3-py2.7-win32.egg \ pymongo \ c on.py「,第435行,在__get_slave_okay中 返回self .__ slave_okay RuntimeError:調用Python對象時超出最大遞歸深度 – user992570

+0

您使用的是什麼模擬庫? – pbacterio

回答

0

對於簡單的傳遞初始化(),我們可以嘲笑pymongo.MongoClient如下:

import unittest 
import pymongo 
from mock import patch 


class MyMongo(object): 
    def initialize(self): 
     try : 
      self.client = pymongo.MongoClient("127.0.0.1", 27017) 
      self.conn = self.client["DB_NAME"] 
     except Exception: 
      print "Except in initialize!" 
      return False 
     return True 


class TestMyMongo(unittest.TestCase): 
    def test_mongodb_initialize_true(self): 
     with patch('pymongo.MongoClient') as mock_mongo: 
      self.mymongo = MyMongo() 
      self.assertEqual(self.mymongo.initialize(), True) 

但是我不知道,如果你想嘲笑MongoClient或只是MongoClient。 init部分?

0

MongoClient的設計不是用這種方式來模擬的。它必須在__init__中初始化它的屬性才能正常工作,所以如果你跳過調用__init__,所有進一步的操作都會拋出各種異常。在你的具體情況下,MongoClient需要訪問__slave_okay屬性,但它沒有設置。

要麼建立一個實際的MongoDB服務器並對它進行測試,要麼用假庫來模擬PyMongo的所有內容。在PyMongo中簡單地重寫一些方法是不合理的。

1

既然你是單元測試,而不是試圖以任何方式實際連接到Mongo,我認爲你應該只關心客戶端API已被調用。所以我建議如下 - (原諒我,如果我的語法是關閉的,我用pytest而不是單元測試)

from unittest import mock 
@mock.patch("pymongo.MongoClient") 
def test_mongodb_initialize(self, mock_pymongo): 
    MyMongo.initialize() 
    self.assertTrue(mock_pymongo.called) 

+0

嗨佩德羅 - 我相信你需要一個MyMongo的實例,所以它應該是:'MyMongo()。initialize()' –