PYTEST:UNITSEST错误对象没有属性' assert_called_once_with

发布于 2025-02-01 05:21:35 字数 1275 浏览 4 评论 0 原文

我正在用pytest编写单元测试,并在assert_called_once_with上获得错误。 我厌倦了使用Pytest文档中所示的相同方式,但似乎我缺少一些东西。

# Class which I am trying to mock. (./src/Trading.py)
class BaseTrade:
    def __init__(self, name):
        self.name = name

class Trade(BaseTrade):
    def __init__ (self, name):
        BaseTrade.__init__(self, name)

    def get_balance(self, value):
        # do calculation and return some value
        # for demo purpose hard-coding it
        return  value * 10


#unit test (./unitest/test_test.py
import mock
import unittest
import sys

sys.path.append("../src")

import Trading

class TestTradeClass(unittest.TestCase):
    @classmethod
    def setUpClass(self):
        self.expected_balance = 100

    @classmethod
    def tearDownClass(self):
        pass
    def test_trade(self):
        with mock.patch.object(Trading.Trade, 'get_balance', new = lambda self, x: (x * 10) ) as mock_method:
            obj = Trading.Trade("AAPL")
            value = obj.get_balance(10)
            assert value == 100
        mock_method.assert_called_once_with(100)
Error on mock_method.assert_called_once_with(100)
  AttributeError: 'function' object has no attribute 'assert_called_once_with'

I am writing unit test in pytest and getting error on assert_called_once_with.
I tired to use same way as been shown in the pytest documentation but seems I am missing something.

# Class which I am trying to mock. (./src/Trading.py)
class BaseTrade:
    def __init__(self, name):
        self.name = name

class Trade(BaseTrade):
    def __init__ (self, name):
        BaseTrade.__init__(self, name)

    def get_balance(self, value):
        # do calculation and return some value
        # for demo purpose hard-coding it
        return  value * 10


#unit test (./unitest/test_test.py
import mock
import unittest
import sys

sys.path.append("../src")

import Trading

class TestTradeClass(unittest.TestCase):
    @classmethod
    def setUpClass(self):
        self.expected_balance = 100

    @classmethod
    def tearDownClass(self):
        pass
    def test_trade(self):
        with mock.patch.object(Trading.Trade, 'get_balance', new = lambda self, x: (x * 10) ) as mock_method:
            obj = Trading.Trade("AAPL")
            value = obj.get_balance(10)
            assert value == 100
        mock_method.assert_called_once_with(100)
Error on mock_method.assert_called_once_with(100)
  AttributeError: 'function' object has no attribute 'assert_called_once_with'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

恍梦境° 2025-02-08 05:21:35

我现在相信您想要 side_effect 。这怎么样?一个文件,假设 test.py

#!/usr/bin/env python
import unittest

import mock


class BaseTrade:
    def __init__(self, name):
        self.name = name


class Trade(BaseTrade):
    def __init__(self, name):
        BaseTrade.__init__(self, name)

    def get_balance(self, value):
        # do calculation and return some value
        # for demo purpose hard-coding it
        return value * 10


class TestTradeClass(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.expected_balance = 100

    def test_trade(self):
        # Without mock
        obj = Trade("AAPL")
        value = obj.get_balance(10)
        assert value == 100

        # With Trade.get_balance param patched
        with mock.patch.object(
            Trade, 'get_balance', side_effect=lambda value: value * 11
        ) as mock_method:
            obj = Trade("AAPL")
            value = obj.get_balance(10)
            assert value == 110
        mock_method.assert_called_once_with(10)


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

chmod +x test.py

./ test.py

输出:

.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

说明:

  • 使用 side> side_fect < /code>而不是
  • 组合到一个文件中,以使其更容易
  • 删除 trade.trade
  • @classmethod 使用 cls 而不是 self
  • MOCK_METHOD.ASSERT_CALLED_ONCE_WITH(10),AS side_feft 关心通过 obj.get_balance(10)和存在以更改输出的值。

更近?如果没有,您可以澄清您要嘲笑什么?

I'm now of the belief you want side_effect. How is this? One file, assume test.py:

#!/usr/bin/env python
import unittest

import mock


class BaseTrade:
    def __init__(self, name):
        self.name = name


class Trade(BaseTrade):
    def __init__(self, name):
        BaseTrade.__init__(self, name)

    def get_balance(self, value):
        # do calculation and return some value
        # for demo purpose hard-coding it
        return value * 10


class TestTradeClass(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.expected_balance = 100

    def test_trade(self):
        # Without mock
        obj = Trade("AAPL")
        value = obj.get_balance(10)
        assert value == 100

        # With Trade.get_balance param patched
        with mock.patch.object(
            Trade, 'get_balance', side_effect=lambda value: value * 11
        ) as mock_method:
            obj = Trade("AAPL")
            value = obj.get_balance(10)
            assert value == 110
        mock_method.assert_called_once_with(10)


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

chmod +x test.py

./test.py

Output:

.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

Explanation:

  • Use side_effect instead of new
  • Combined to one file to make it easier
  • removing Trading.Trade
  • @classmethod to use cls and not self.
  • mock_method.assert_called_once_with(10), as side_effect cares about the value passed via obj.get_balance(10) and exists to alter the output.

Closer? If not can you clarify what you're trying to mock?

姐不稀罕 2025-02-08 05:21:35

这并不容易,但是如果 trade.trade.get_method()实际上是一种香草功能,而不是一种方法 - 您可能需要 unittest.mock.create_autospec()

是否有任何帮助?

不清楚whaat trade.trade.trade.trade 是。

如果偶然,交易是一个具有 self.trade = Trade(...)内部的类,您的问题将大不相同。然后,您需要进行更深入的修补 trade.get_method 。您可能想从同一模块中导入交易类交易使用它(例如,从.trading Import Trading,Trade Trade ) - 不是从其中 trade 从 - 然后修补 trade.get_method

It's not easy to tell, but if Trading.Trade.get_method() is actually a vanilla function and not a method - you may need unittest.mock.create_autospec()

Are any of these of assistance?

It's not clear whaat Trading.Trade is.

If by chance, Trading is a class that has a self.trade = Trade(...) inside, your question would be substantially different. You'd need to get in deeper, patching Trade.get_method, then. You'd likely want to import Trade from the same module class Trading uses it (e.g. from .trading import Trading, Trade) - not from where Trade is declared from - then patch the Trade.get_method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文