gpt4 book ai didi

python - 模拟类方法并更改 Python 中的一些对象属性

转载 作者:太空狗 更新时间:2023-10-29 21:25:50 25 4
gpt4 key购买 nike

我是 Python 模拟新手。我想知道如何在用另一个类方法进行测试时替换(模拟)一个类方法,知道原始方法只是更改了 self 的某些属性而不返回任何值。例如:

def some_method(self):   
self.x = 4
self.y = 6

所以在这里我不能只更改模拟的 return_value。我试图定义一个新函数(应该替换原来的函数)并将其作为 side_effect 提供给模拟。但是我怎样才能让模拟函数改变类中对象的属性。这是我的代码:

@patch('path.myClass.some_method')
def test_this(self,someMethod):

def replacer(self):
self.x = 5
self.y = 16

some_method.side_effect = replacer

那么 Python 现在是如何理解 replacer 的 self 参数的呢?是测试类的self,还是被测类的对象self?

最佳答案

如果我不明白您要做什么,请提前致歉,但我认为这可能有效:

import unittest
from unittest.mock import patch

class MyClass:

def __init__(self):
self.x = 0
self.y = 0

def some_method(self):
self.x = 4
self.y = 6

class OtherClass:

def other_method(self):
self.x = 5
self.y = 16

class MyTestClass(unittest.TestCase):

@patch('__main__.MyClass.some_method', new=OtherClass.other_method)
def test_patched(self):
a = MyClass()
a.some_method()
self.assertEqual(a.x, 5)
self.assertEqual(a.y, 16)

def test_not_patched(self):
a = MyClass()
a.some_method()
self.assertEqual(a.x, 4)
self.assertEqual(a.y, 6)

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

这会在修补时用 other_method() 替换 some_method() ,这会为属性 x、y 设置不同的值,并且在运行测试时,它会给出结果:

..
----------------------------------------------------------------------
Ran 2 tests in 0.020s

OK

编辑:回答有关如何在不模拟类的情况下在测试函数内部执行的问题...

def test_inside_patch(self):
def othermethod(self):
self.x = 5
self.y = 16
patcher = patch('__main__.MyClass.some_method', new=othermethod)
patcher.start()
a = MyClass()
a.some_method()
self.assertEqual(a.x, 5)
self.assertEqual(a.y, 16)
patcher.stop()

确保您在补丁程序上调用了 start() 和 stop() ,否则您可能会遇到补丁处于事件状态但您不希望它处于事件状态的情况。请注意,要在测试代码函数中定义 mock 函数,我没有使用 patch 作为装饰器,因为必须在 patch 中使用“new”关键字之前定义 mock 函数。如果你想使用 patch 作为装饰器,你必须在 patch 之前的某个地方定义 mock 函数,在 MyTestClass 中定义它也可以,但看起来你真的想在你的测试函数代码中定义 mock 函数。

编辑:添加了我看到的 4 种方法的摘要...

# first way uses a class outside MyTest class
class OtherClass:
def other_method(self):
...

class MyTest(unittest.TestCase):

@patch('path_to_MyClass.some_method', new=OtherClass.other_method)
def test_1(self)
...

# 2nd way uses class defined inside test class
class MyOtherClass:
def other_method(self):
...
@patch('path_to_MyClass.some_method', new=MyOtherClass.other_method)
def test_2(self):
...

# 3rd way uses function defined inside test class but before patch decorator
def another_method(self):
...
@patch('path_to_MyClass.some_method', new=another_method)
def test_3(self):
...

# 4th way uses function defined inside test function but without a decorator
def test_4(self):
def yet_another_method(self):
...
patcher = patch('path_to_MyClass.some_method', new=yet_another_method)
patcher.start()
...
patcher.stop()

这些都没有使用副作用,但它们都解决了模拟类方法和更改某些属性的问题。您选择哪一个取决于应用程序。

关于python - 模拟类方法并更改 Python 中的一些对象属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34406848/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com