2016-08-17 63 views
5

我想在python中做一個簡單的測試,但我無法弄清楚如何完成嘲諷過程。模擬整個Python類

這是類和DEF代碼:

class FileRemoveOp(...) 
    @apply_defaults 
    def __init__(
      self, 
      source_conn_keys, 
      source_conn_id='conn_default', 
      *args, **kwargs): 
     super(v4FileRemoveOperator, self).__init__(*args, **kwargs) 
     self.source_conn_keys = source_conn_keys 
     self.source_conn_id = source_conn_id 


    def execute (self, context) 
      source_conn = Connection(conn_id) 
      try: 
       for source_conn_key in self.source_keys: 
        if not source_conn.check_for_key(source_conn_key):  
         logging.info("The source key does not exist") 
        source_conn.remove_file(source_conn_key,'') 
      finally: 
       logging.info("Remove operation successful.") 

這是我的測試執行功能:

@mock.patch('main.Connection') 
def test_remove_execute(self,MockConn): 
    mock_coon = MockConn.return_value 
    mock_coon.value = #I'm not sure what to put here# 
    remove_operator = FileRemoveOp(...) 
    remove_operator.execute(self) 

由於執行方法嘗試建立連接,我需要嘲笑這一點,我不想建立真正的聯繫,只是回報一些模擬。我怎麼能做到這一點?我習慣在Java中進行測試,但是我從來沒有在python上做過測試。

+1

你究竟想要測試什麼?通常你正在嘲笑你正在測試的代碼所調用的東西,並且不要直接調用模擬。用你的方法你只會測試模擬。 –

+0

更完整的例子會很有用。很難衡量你想要達到的目標。也就是說,當模擬類被調用時,它會自動創建另一個模擬作爲返回的實例。然後您可以根據需要設置此模擬連接。 – Dunes

回答

8

首先,明白你總是需要模擬它在你試圖模擬出來的東西的地方是如何使用的unittest.mock文檔。

基本原理是,你修補了一個物體被查找的位置,它不一定與它定義的位置相同。

下一步你需要做的是返回一個MagicMock實例作爲return_value修補對象。所以總結一下,你需要使用以下順序。

  • 片對象
  • 準備MagicMock使用
  • 回報,我們剛剛創建的MagicMockreturn_value

這裏的一個項目的一個簡單的例子。

connection.py(類我們想模擬)

class Connection(object):               
    def execute(self):               
     return "Connection to server made" 

file.py(當使用類)

from project.connection import Connection           


class FileRemoveOp(object):              
    def __init__(self, foo):              
     self.foo = foo               

    def execute(self):               
     conn = Connection()              
     result = conn.execute()             
     return result  

測試/ test_file.py

import unittest                 
from unittest.mock import patch, MagicMock          
from project.file import FileRemoveOp            

class TestFileRemoveOp(unittest.TestCase):          
    def setUp(self):                
     self.fileremoveop = FileRemoveOp('foobar')        

    @patch('project.file.Connection')            
    def test_execute(self, connection_mock): 
     # Create a new MagickMock instance which will be the 
     # `return_value` of our patched object          
     connection_instance = MagicMock()           
     connection_instance.execute.return_value = "testing" 

     # Return the above created `connection_instance`      
     connection_mock.return_value = connection_instance      

     result = self.fileremoveop.execute()          
     expected = "testing"              
     self.assertEqual(result, expected)          

    def test_not_mocked(self): 
     # No mocking involved will execute the `Connection.execute` method             
     result = self.fileremoveop.execute()          
     expected = "Connection to server made"         
     self.assertEqual(result, expected) 
+0

非常感謝!這是一個完美的例子,並且正確運作! :) – AnaF