断言没有使用Mock调用函数/方法

Ger*_*ard 117 python unit-testing mocking python-mock

我正在使用Mock库来测试我的应用程序,但我想断言某些函数没有被调用.模拟文档讨论像mock.assert_called_with和的方法mock.assert_called_once_with,但我没有发现任何类似mock.assert_not_called或与确认模拟相关的东西没有调用.

我可以使用类似下面的东西,虽然它看起来不酷也不像pythonic:

def test_something:
    # some actions
    with patch('something') as my_var:
        try:
            # args are not important. func should never be called in this test
            my_var.assert_called_with(some, args)
        except AssertionError:
            pass  # this error being raised means it's ok
    # other stuff
Run Code Online (Sandbox Code Playgroud)

任何想法如何实现这一目标?

谢谢你的帮助 :)

Joa*_*son 132

这适用于你的情况;

assert not my_var.called, 'method should not have been called'
Run Code Online (Sandbox Code Playgroud)

样品;

>>> mock=Mock()
>>> mock.a()
<Mock name='mock.a()' id='4349129872'>
>>> assert not mock.b.called, 'b was called and should not have been'
>>> assert not mock.a.called, 'a was called and should not have been'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: a was called and should not have been
Run Code Online (Sandbox Code Playgroud)


Ahm*_*met 54

虽然是一个老问题,但我想补充一点,目前mock库(unittest.mock的backport)支持assert_not_called方法.

只需升级你的;

pip install mock --upgrade


Rob*_*edy 28

您可以检查called属性,但是如果您的断言失败,那么您想要知道的下一件事是关于意外调用的事情,因此您也可以安排从一开始就显示该信息.使用unittest,您可以检查内容call_args_list:

self.assertItemsEqual(my_var.call_args_list, [])
Run Code Online (Sandbox Code Playgroud)

当它失败时,它会给出如下消息:

AssertionError: Element counts were not equal:
First has 0, Second has 1:  call('first argument', 4)


val*_*lex 23

随着python >= 3.5你可以使用mock_object.assert_not_called().


Hun*_*_71 12

当您使用类继承unittest.TestCase进行测试时,您可以简单地使用以下方法:

  • assertTrue
  • assertFalse
  • assertEqual便

和类似的(在python文档中,你找到其余的).

在您的示例中,我们可以简单地断言mock_method.called属性是否为False,这意味着未调用该方法.

import unittest
from unittest import mock

import my_module

class A(unittest.TestCase):
    def setUp(self):
        self.message = "Method should not be called. Called {times} times!"

    @mock.patch("my_module.method_to_mock")
    def test(self, mock_method):
        my_module.method_to_mock()

        self.assertFalse(mock_method.called,
                         self.message.format(times=mock_method.call_count))
Run Code Online (Sandbox Code Playgroud)

  • 我不明白为什么这个答案的票数这么少......对我来说,这是正确的答案! (2认同)