2016-04-11 38 views
0

我正在編寫單元測試來驗證我的項目功能。我需要用模擬函數替換一些函數,我想用Python模擬庫。我使用的實現似乎沒有正常工作,但我不明白我做錯了什麼。這裏的簡化情形:Python:關於構建模擬函數的問題

根/ connector.py

from ftp_utils.py import * 

def main(): 
    config = yaml.safe_load("vendor_sftp.yaml") 
    downloaded_files = [] 

    downloaded_files = get_files(config) 
    for f in downloaded_files: 
     #do something 

根/ utils的/ ftp_utils.py

import os 
import sys 
import pysftp 

def get_files(config): 
    sftp = pysftp.Connection(config['host'], username=config['username']) 
    sftp.chdir(config['remote_dir']) 
    down_files = sftp.listdir() 
    if down_files is not None: 
    for f in down_files: 
     sftp.get(f, os.path.join(config['local_dir'], f), preserve_mtime=True) 

    return down_files 

根/測試/ connector_tester.py

import unittest 
import mock 
import ftp_utils 
import connector 

def get_mock_files(): 
    return ['digital_spend.csv', 'tv_spend.csv'] 

class ConnectorTester(unittest.TestCase) 
    @mock.patch('ftp_utils.get_files', side_effect=get_mock_files) 
    def test_main_process(self, get_mock_files_function): 
    # I want to use a mock version of the get_files function 
    connector.main() 

當我調試我的測試時,我期望在connector.py的main中調用的get_files函數是get_mock_files(),而是ftp_utils.get_files()。我在這裏做錯了什麼?我應該更改我的代碼以正確調用get_mock_file()模擬?

感謝, 阿萊西奧

回答

1

我覺得有幾個問題,您的方案:

  • connector.py不能從ftp_utils.py這樣
  • 也不能connector_tester.py
  • 作爲一種習慣,它是進口更好地讓您的測試文件的形式test_xxx.py
  • 使用unittest與修補,見this example

一般情況下,儘量提供工作最少例子所以這是大家來運行你的代碼更容易。

我修改,而大量的例子,使其工作,但基本上,問題是,你修補'ftp_utils.get_files'雖然它不是實際上是所謂的內部connector.main()但可能寧願'connector.get_files'參考。

下面是修改的例子的目錄:

test_connector.py 
ftp_utils.py 
connector.py 

test_connector.py:

import unittest 
import sys 
import mock 
import connector 

def get_mock_files(*args, **kwargs): 
    return ['digital_spend.csv', 'tv_spend.csv'] 

class ConnectorTester(unittest.TestCase): 
    def setUp(self): 
     self.patcher = mock.patch('connector.get_files', side_effect=get_mock_files) 
     self.patcher.start() 

    def test_main_process(self): 
     # I want to use a mock version of the get_files function 
     connector.main() 

suite = unittest.TestLoader().loadTestsFromTestCase(ConnectorTester) 

if __name__ == "__main__": 
    unittest.main() 

NB:運行connector.main()當所謂的'connector.get_files'

connector.py:

from ftp_utils import * 

def main(): 
    config = None 
    downloaded_files = [] 
    downloaded_files = get_files(config) 
    for f in downloaded_files: 
     print(f) 

connector/ftp_utils.py不變。

+0

感謝您的意見。 我已經指出這是一個簡化版本,如果我沒有進一步指定,請道歉。 爲什麼我們需要編寫另一個模塊(content.py)?這不是非常簡單,需要一些工作。 請問您能指出我的例子中出了什麼問題嗎? – AlessioG

+0

正如我所說,你的例子不能工作,因爲所有的進口是無效的...所以我不能真正告訴你什麼是錯的... 基本上,如果你有一個版本,在您的計算機上進口是正確的,你需要在connector.main()中調用'''ftp_utils.get_files''到函數的正確路徑,可能類似''connector.ftp_utils.get_files'' ...但是如果你的文件夾看起來像你在例子中給出的,你真的**應該考慮重組! – Silmathoron

+1

好吧,如果你不想使用一個完整的模塊,我編輯了與同一文件夾中的所有文件的示例(事實上,您在示例中使用的文件夾使我認爲這是您的計算機上的文件) 。修正代碼的想法就是如果你在''connector.py''裏面導入''get_files'',那麼你需要修補'''connector.get_files'''。 – Silmathoron