我正在尝试对some_function
实例方法MyClass
进行单元测试,该方法需要someapi.api
实例。如何用一些返回值修补self.api.something1.something2(foo)
?
import someapi
class MyClass(object):
def __init__(self,a,b):
self.a = a
self.b = b
self.api = someapi.api(self.a, self.b)
def some_function(self, foo):
result = self.api.something1.something2(foo)
new_result = dosomething(result)
return new_result
所以我真正想要的是模拟此api的响应,以便我可以测试dosomething(result)
是否满足我的要求。
@mock.patch('self.api.something1.something2', side_effect='something')
def testGet_circuits(self,pymock):
result = some_function('foobar')
expected_result= 'something'
self.assertEqual(result, 'expected_result')
我尝试了
@mock.patch('someapi.api')
def testSome_function(self,someapi_mock):
api = MyClass('a','b')
result = api.some_function('foo')
self.assertEqual(result,'newfoo')
我正在努力解决的是如何在some_function中模拟self.api.something1.something2(foo)
:(
答案 0 :(得分:0)
您没有正确设置模拟。我使用您的代码编写了一个示例,并设法将一个有效的测试方法组合在一起。最终,这里发生的是您没有告诉模拟程序在代码运行时如何表现。您可能在正确的地方开始了模拟,但除此之外,模拟本身不再具有要允许代码运行而试图访问的任何属性。我将遍历代码来帮助说明:
class TestStuff(unittest.TestCase):
@mock.patch('real_code.someapi.api', autospec=True)
def testSome_function(self, someapi_mock):
someapi_mock.return_value.something1 = mock.Mock(spec=Something)
someapi_mock.return_value.something1.something2.return_value = 'newfoo'
api = MyClass('a', 'b')
result = api.some_function('foo')
self.assertEqual(result, 'newfoo')
第一件事,请注意,我正在针对测试位置进行更多的嘲笑,这一点很重要,请牢记,您应该阅读here。
对于模拟配置问题,我只能从您的真实代码中假设,api.something1.something2
指示something1
持有其他某个类的实例,该类使您可以访问something2
方法。因此,在此假设下说明了示例。
现在,正如您在方法的第一行中看到的那样,我正在做的是告诉我的模拟确保它具有something1
属性。重要的是要记住,在进行模拟时,甚至在设置spec and/or autospec时(如我在示例中所使用的),也无法访问在__init__
中创建的属性。因此,根据我的示例,您需要在模拟中提供它们。
第二行现在进行下一步,以模拟您试图从中获取结果的something2
方法行为。完成此操作后,在调用您的真实代码时,它应该经历您设置的预期行为并返回预期的newfoo
值。
要获得进一步的帮助,以下是我用来帮助进行功能测试的确切代码:
import someapi
class MyClass(object):
def __init__(self,a,b):
self.a = a
self.b = b
self.api = someapi.api(self.a, self.b)
def some_function(self, foo):
result = self.api.something1.something2(foo)
new_result = dosomething(result)
return new_result
def dosomething(foo):
return foo
class api:
def __init__(self, a, b):
self.a = a
self.b = b
self.something1 = Something()
class Something:
def something2(self, some_arg):
return some_arg
答案 1 :(得分:0)
感谢所有答案对我的帮助 我结束了下面的工作,像个魅力。整个模拟过程看起来像兔子洞,我需要更深入地理解。
@mock.patch('someapi.api')
def testSome_function(self,someapi_mock):
someapi_mock = return_value.something1.something2.return_value = 'mocked_value'
api = MyClass('a','b')
result = api.some_function('foo')
self.assertEqual(result,'newfoo')