2015-12-22 45 views
0

我在模擬functiog時遇到了一些麻煩。所述功能導入並run_parsers.py使用,我得到Mock在修補導入的模塊時返回ImportError

ImportError: 'No module named run_parsers' 

當我試圖mock.patchrun_parsers.py

下面是test_run_parsers.py

from .. import run_parsers # Used in all my other tests. 

def test_node_data_parser_throws_exception(self): 
    def parser(): 
     return NotImplementedError() 

    with mock.patch("run_parsers.get_node_paths") as node_paths: 
     node_paths.return_value = "node_1" 
     run_parsers.get_node_data(parser, "https://stackoverflow.com/a/path") 

我的測試代碼,這裏是我的倉庫結構

control_scripts 
├── __init__.py 
├── README.md 
├── run_all_parsers.py 
├── run_parsers.py 
└── tests 
    ├── __init__.py 
    ├── test_run_parsers.py 

According to this tutorial I'm supposed to mock where the function is imported.這就是爲什麼我試圖嘲弄調用模塊,而不是定義get_node_paths

模塊
+0

我看到你嘲諷「run_parsers.get_node_paths」但你不調用該函數,你叫「run_parsers.get_node_data」。這是一個錯字嗎?或者是「run_parsers.get_node_data」調用的「run_parsers.get_node_paths」? –

+0

另一個問題:你嘗試使用絕對導入「import run_parsers」並確保目錄「control_scripts」在你的sys.path上(作爲測試用例)嗎?這只是爲了首先測試模擬函數按預期工作,然後您可以解決導入問題。這就是我通常試圖解決這些問題的方法。 –

+0

@SteveMisuta這不是一個錯字。我試圖測試'get_node_data','get_node_data'調用的其中一個函數是'get_node_paths'。 我還沒有檢查,看看control_scripts是否在路徑中。我必須去看看,但我很確定它不是。 – AlexLordThorsen

回答

1

我不確定這是否完全重複您的設置,但是這裏有一個簡單的測試案例適用於我。

的目錄設置爲:

c:\work 
    \control 
     __init__.py 
     scripts.py 
     \tests 
      __inti__.py 
      mytests.py 

and c:\work is on sys.path 

在模塊scripts.py:

def identity(x): 
    return x 

def do_identity(x): 
    return identity(x) 

在mytests.py:

import unittest 
from unittest.mock import patch 
from control import scripts 

class MyTest(unittest.TestCase): 

    def test_patch(self): 

     with patch('control.scripts.identity') as mymock: 
      mymock.return_value = 99 
      self.assertEqual(scripts.do_identity(1), 99) 

    def test_no_patch(self): 

      self.assertEqual(scripts.do_identity(1), 1)    

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

所以我想在這裏做就是模擬函數'do_identity'調用的函數'identity'。這兩個函數都在'腳本'模塊中。此測試運行時沒有錯誤或失敗。

而且我可以從任何目錄中運行以下命令:

c:\any_directory> python c:\work\control\tests\mytests.py 
+0

確認我需要使用絕對導入,並且他父目錄需要在路徑上。可能有一種方法可以在案例中使用相對導入,但這是我最終使用的解決方案。 – AlexLordThorsen

+0

太棒了!最近我一直在使用完全路徑絕對導入語句,特別是在測試中。然後,我可以從任何地方運行測試作爲程序或模塊,以及交互式工作。此方法也適用於Python 2和3,即使它們使用不同的導入方案。您只需將結構設置爲top \ pkg \ sub1 \ sub2 \ mod1.py並確保top位於sys.path中。然後像'從pkg.sub1.sub2導入mod1'或類似的導入將始終工作。相對進口具有優勢,但最終使用它們似乎會遇到麻煩,而且我沒有時間去調試導入失敗。 –

相關問題