模拟整个 python 类 [英] Mock entire python class

查看:30
本文介绍了模拟整个 python 类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 python 中进行一个简单的测试,但我无法弄清楚如何完成模拟过程.

I'm trying to make a simple test in python, but I'm not able to figure it out how to accomplish the mocking process.

这是类和定义代码:

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.")

这是我对执行函数的测试:

And this is my test for the execute function:

@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)

由于 execute 方法尝试建立连接,我需要模拟它,我不想建立真正的连接,只需返回一些模拟即可.我怎样才能做到这一点?我习惯用 Java 做测试,但我从来没有在 python 上做过..

Since the execute method try to make a connection, I need to mock that, I don't want to make a real connection, just return something mock. How can I make that? I'm used to do testing in Java but I never did on python..

推荐答案

首先很重要的一点是要明白,你总是需要在 unittest 中说明的地方使用你试图模拟的东西.mock 文档.

First it is very important to understand that you always need to Mock where it the thing you are trying to mock out is used as stated in the unittest.mock documentation.

基本原理是在查找对象的地方打补丁,这不一定与定义的地方相同.

The basic principle is that you patch where an object is looked up, which is not necessarily the same place as where it is defined.

接下来您需要做的是返回一个 MagicMock 实例作为修补对象的 return_value.因此,为了总结这一点,您需要使用以下顺序.

Next what you would need to do is to return a MagicMock instance as return_value of the patched object. So to summarize this you would need to use the following sequence.

  • 补丁对象
  • 准备要使用的MagicMock
  • 返回我们刚刚创建的 MagicMock 作为 return_value

这是一个项目的简单示例.

Here a quick example of a project.

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    

tests/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) 

这篇关于模拟整个 python 类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆