在类属性中模拟实例化类

问题描述 投票:0回答:1

我正在开发一个项目,该项目使用名为

Deck
的类从 API 获取数据。该类通过其
Game Manager
(顺便说一句,这是一个二十一点游戏)在另一个名为
__init__
的类中实例化,如下所示:

服务器/game_manager.py

import .deck import Deck
  
class GameManager:
      self._deck = Deck()

服务器/deck.py

class Deck:
      def fetch_cards(self):
          '''Method that gets cards from api'''
          pass

现在,我在模拟

attribute not found
类以避免连接到 API 时遇到了无法解决的
Deck
错误。我的测试是这样的:

服务器/测试/game_manager_test.py

import unittest
from unittest.mock import patch, Mock
from ..game_manager import *

gm = GameManager()

class TestCardDraw(unittest.TestCase):
      @patch("server.game_manager.deck")
      def test_draw_game_start_cards(self, deck_mock):
          deck_mock = Mock()
          deck_mock.fetch_cards.return_value = [7,2]
          self.assertEqual(len(gm._game_state["player_one"]["cards"]), 2)

Attribute Error: module 'server.game_manager' does not the attribute 'deck'

我想向社区询问几个问题,以了解我做错了什么。

  1. 我应该模拟从
    server/game_manager.py
    导入的 deck 模块还是从
    server/deck.py
    模块本身导入 deck 模块?
  2. 执行其中一项或另一项有什么区别?
  3. 我正在测试套件的顶部创建一个
    GameManager
    的实例,以测试同一实例中的一些方法。我在其中一个测试套件中更改了此实例的值,以获得我想要的结果
    setUp
    。我应该模拟我用于测试的实例的
    fetch_cards
    方法,还是应该保留我想要进行的特定测试的模拟策略。这两种方法有什么区别?

最后,我已经遵循了文档中的示例以及 Stack Overflow 的答案,但此时我对理解要模拟什么以及如何模拟感到困惑。在代码中得到答案总是很酷,但我想看看我的思维过程中我的知识差距在哪里。

python unit-testing mocking
1个回答
0
投票

Deck 对象需要在使用它的上下文中进行修补。

由于

GameManager
对象在您的测试模块中实例化,因此它提供了补丁的上下文。

您必须修补

_deck
对象的
gm
属性,并配置
MagicMock
实例
,以在调用
fetch_cards
方法时返回列表。

gm = GameManager()

class TestCardDraw(unittest.TestCase):
    @patch.object("gm", "_deck")
    def test_draw_game_start_cards(self, deck_mock):
        deck_mock.configure_mock(**{'fetch_cards.return_value': [7, 2]})
        #...
        self.assertEqual(len(gm._game_state["player_one"]["cards"]), 2)
© www.soinside.com 2019 - 2024. All rights reserved.