如何模拟辅助类的 init

jku*_*urs -1 python unit-testing mocking pytest python-3.x

我在检查一个对象是否是使用另一个对象实例的正确参数构造时遇到问题。在下面的示例中,我尝试B在 的实例中创建 的实例AB我想检查实例内部构造函数中使用的参数A。当我运行下面的测试时,我得到:

AssertionError: assert None
[CPython36:setup:stdout] E        +  where None = <bound method NonCallableMock.assert_called_with of <MagicMock name='B' id='139968329210736'>>(4)
[CPython36:setup:stdout] E        +    where <bound method NonCallableMock.assert_called_with of <MagicMock name='B' id='139968329210736'>> = <MagicMock name='B' id='139968329210736'>.assert_called_with
Run Code Online (Sandbox Code Playgroud)

我不太确定我在这里做错了什么,并查看了其他堆栈溢出帖子,但无法解决我的问题。

b.py:

class B(object):
    def __init__(self, x):
        self.x = x

    def square(self):
        return x * x
Run Code Online (Sandbox Code Playgroud)

a.py:

from b import B

class A(object):
    def foo(self):
        b = B(4)
        b.square()
Run Code Online (Sandbox Code Playgroud)

测试_a.py:

import unittest
from unittest.mock import patch

from a import A

class TestA(unittest.TestCase):  

    @patch('a.B')
    def test_foo(self, mock_b):
        self.a = A()
        self.a.foo()
        assert mock_b.assert_called_with(4)
Run Code Online (Sandbox Code Playgroud)

Jos*_*ilo 6

该方法assert_called_with返回 None,所以你正在做的就像做

assert None
Run Code Online (Sandbox Code Playgroud)

这基本上就是您收到的错误消息。

你可以只使用

mock_b.assert_called_with(4)
Run Code Online (Sandbox Code Playgroud)

它内部有一个断言,如果失败,pytest 将正确显示它。尝试通过更改参数值来检查它。

或者,如果您更喜欢自己编写断言,则可以执行以下操作:

from unittest.mock import call
assert mock_b.call_args_list == [call(4)]
Run Code Online (Sandbox Code Playgroud)

或者只是最后一个电话:

from unittest.mock import call
assert mock_b.call_args == call(4)
Run Code Online (Sandbox Code Playgroud)