python @patch 自定义修补对象未更新

问题描述 投票:0回答:1

我想用我自己的模拟版本(

func_to_be_mocked 
)修补一个返回类对象(
ReturnValue
)的函数(
ReturnValueMock
)。我想测试的功能(
func_to_be_tested
)正在为对象设置一些值。但我的模拟对象没有更新并显示默认值。 (即测试中的断言语句失败)。我错过了什么?

to_test.py

class ReturnValue():
  def __init__(self):
    self.a = ""

class ToTest():

  def func_to_be_mocked(self):
    return ReturnValue()

  def func_to_be_tested(self):
    ret_val = self.func_to_be_mocked()
    ret_val.a = "set"

测试.py

from mock import patch
import unittest
from .to_test import ToTest

class ReturnValueMock():
  def __init__(self):
    self.a = ""


class Tests(unittest.TestCase):

  def setUp(self):
    self.ret_val = ReturnValueMock()

  @patch("to_test.ToTest.func_to_be_mocked")
  def test(self, mocked_func):
    mocked_func.return_val = self.ret_val
    ToTest().func_to_be_tested()
    assert self.ret_val == "set"

到目前为止已经尝试过的事情

  • 添加了打印语句以验证被测函数中的对象是否与我作为模拟提供的对象相同(对象哈希码代码相同)
python mocking python-unittest patch python-mock
1个回答
0
投票

这是一个例子:

# run.py
from unittest import TestCase
from unittest.mock import PropertyMock, patch
from datetime import datetime


class ReturnValue:
    def __init__(self):
        self.a = ''


class ToTest:
    def func_to_be_mocked(self):
        return ReturnValue()

    def func_to_be_tested(self):
        ret_val = self.func_to_be_mocked()
        ret_val.a = 'set'
        return ret_val


class ReturnValueMock:
    def __init__(self, a: str):
        self.a = a


class Tests(TestCase):
    def test(self):
        # just demo before patching
        obj = ToTest()
        self.assertTrue(isinstance(obj.func_to_be_tested(), ReturnValue))

        first_result = ReturnValueMock('first')
        self.assertEqual(first_result.a, 'first')

        second_result = ReturnValueMock('second')
        self.assertEqual(second_result.a, 'second')

        # let's change result of func_to_be_mocked() from ReturnValue to ReturnValueMock
        with patch(
          # change run to your module...
          'run.ToTest.func_to_be_mocked',
          side_effect=[first_result, second_result]
        ):
            self.assertTrue(isinstance(obj.func_to_be_tested(), ReturnValueMock))
            self.assertEqual(first_result.a, 'set')

            self.assertTrue(isinstance(obj.func_to_be_tested(), ReturnValueMock))
            self.assertEqual(second_result.a, 'set')

#============================= test session starts #==============================
#collecting ... collected 1 item
#
#run.py::Tests::test PASSED                                             [100%]
#
#============================== 1 passed in 2.87s #===============================
© www.soinside.com 2019 - 2024. All rights reserved.