Python的Mock模擬測試介紹(5)

發表于:2014-03-21來源:DiggerPlus作者:DiggerPlus點擊數: 標簽:模擬測試
太棒了!我們驗證了上傳服務成功調用了實例的rm方法。你是不是注意到這當中有意思的地方了?這種修補機制實際上取代了我們的 測試方法 的刪除服務實例

  太棒了!我們驗證了上傳服務成功調用了實例的rm方法。你是不是注意到這當中有意思的地方了?這種修補機制實際上取代了我們的測試方法的刪除服務實例的rm方法。這意味著,我們實際上可以檢查該實例本身。如果你想了解更多,可以試著在模擬測試的代碼中下斷點來更好的認識這種修補機制是如何工作的。

  陷阱:裝飾的順序

  當使用多個裝飾方法來裝飾測試方法的時候,裝飾的順序很重要,但很容易混亂?;旧?,當裝飾方法唄映射到帶參數的測試方法中時,裝飾方法的工作順序是反向的。比如下面這個例子:

1
2
3
4
5
@mock.patch('mymodule.sys')
@mock.patch('mymodule.os')
@mock.patch('mymodule.os.path')
def test_something(self, mock_os_path, mock_os, mock_sys):
    pass

  注意到了嗎,我們的裝飾方法的參數是反向匹配的? 這是有部分原因是因為Python的工作方式。下面是使用多個裝飾方法的時候,實際的代碼執行順序:

1
patch_sys(patch_os(patch_os_path(test_something)))

  由于這個關于sys的補丁在最外層,因此會在最后被執行,使得它成為實際測試方法的最后一個參數。請特別注意這一點,并且在做測試使用調試器來保證正確的參數按照正確的順序被注入。

  選項2: 創建模擬測試接口

  我們可以在UploadService的構造函數中提供一個模擬測試實例,而不是模擬創建具體的模擬測試方法。 我推薦使用選項1的方法,因為它更精確,但在多數情況下,選項2是必要的并且更加有效。讓我們再次重構我們的測試實例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
from mymodule import RemovalService, UploadService
import mock
import unittestclass 
 
RemovalServiceTestCase(unittest.TestCase):
 
    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # instantiate our service
        reference = RemovalService()        
        # set up the mock
        mock_path.isfile.return_value = False
 
        reference.rm("any path")        
        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")        
        # make the file 'exist'
        mock_path.isfile.return_value = True
 
        reference.rm("any path")
 
        mock_os.remove.assert_called_with("any path")      
 
class UploadServiceTestCase(unittest.TestCase):
 
    def test_upload_complete(self, mock_rm):
        # build our dependencies
        mock_removal_service = mock.create_autospec(RemovalService)
        reference = UploadService(mock_removal_service)        
        # call upload_complete, which should, in turn, call `rm`:
        reference.upload_complete("my uploaded file")        
        # test that it called the rm method
        mock_removal_service.rm.assert_called_with("my uploaded file")

原文轉自:http://www.diggerplus.org/archives/2704

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97