【问题标题】:Hard time debugging AttributeError: module 'game' has no attribute 'get_player_names'很难调试 AttributeError:模块“游戏”没有属性“get_player_names”
【发布时间】:2016-12-28 14:19:43
【问题描述】:

我真的很努力在测试驱动的基本骰子游戏中实现模拟对象。但是,当我运行测试时(见下文),它显示“AttributeError”,我只是不明白为什么?

这是我的单元测试 (test_game.py) 实现:

from unittest import TestCase, mock

import game

class GameTest(TestCase):

    def test_get_player_names(self):
        """Players can enter their names"""

        fake_input = mock.Mock(side_effect=['A', 'M', 'Z', ''])

        with mock.patch('builtins.input', fake_input):
            names = game.get_player_names()

        self.assertEqual(names, ['A', 'M', 'Z'])

    def test_get_player_names_stdout(self):
        """Check the prompts for player names"""

        with mock.patch('builtins.input', side_effect=['A', 'B', '']) as fake:
            game.get_player_names()

        fake.assert_has_calls([
            mock.call("Player 1's name: "),
            mock.call("Player 2's name: "),
            mock.call("Player 3's name: ")
        ])

这是我在 Python 中的实际代码 (game.py):

class Dice:

    def __init__(self, *players):
        self.players = players

    def get_players(self):
        """Return a tuple of all players"""
        return self.players

    def get_player_names():
        """Prompt for player names"""
        names = []

        while True:
            value = input("Player {}'s name: ".format(len(names) + 1))
            if not value:
                break

            names.append(value)

        return names

测试错误显示 (PowerShell):

PS C:\Users\Seun\desktop\dice> python -m unittest

-------------------------------------------------- --------------------
在 0.000 秒内运行 0 次测试

好的
PS C:\Users\Seun\desktop\dice> python3 -m unittest
EE。
==================================================== =====================
错误:test_get_player_names (test_game.GameTest)
玩家可以输入他们的名字
-------------------------------------------------- --------------------
回溯(最近一次通话最后):
  文件“C:\Users\Seun\desktop\dice\test_game.py”,第 19 行,在 test_get_player_names
    名称 = game.get_player_names()
AttributeError:模块“游戏”没有属性“get_player_names”

==================================================== =====================
错误:test_get_player_names_stdout (test_game.GameTest)
检查玩家姓名的提示
-------------------------------------------------- --------------------
回溯(最近一次通话最后):
  文件“C:\Users\Seun\desktop\dice\test_game.py”,第 27 行,在 test_get_player_names_stdout
    game.get_player_names()
AttributeError:模块“游戏”没有属性“get_player_names”

-------------------------------------------------- --------------------
在 0.009 秒内运行 3 次测试

失败(错误=2)

【问题讨论】:

  • 游戏在哪里初始化,你导入游戏但是代码在哪里?
  • 第二个代码集——game.py

标签: python unit-testing tdd


【解决方案1】:

game.get_player_names 在您的测试类中,您指向名为“get_player_names”的方法在名为“游戏”的模块中

但是game.py 公开了一个Dice 类,该类公开了get_player_names。所以你必须导入模块,实例化一个 Dice 实例,然后从实例调用get_player_names

from game import Dice
class GameTest(TestCase):
    # [ ... your code ...]
    game = Dice('player1', 'player2')
    game.get_player_names() # <== works.

顺便说一下,traceback 很明确:AttributeError: module 'game' has no attribute 'get_player_names'module 'game' 是重要的部分。

【讨论】:

    【解决方案2】:

    您的测试正在导入一个名为“游戏”的module。 在此模块中,您有一个 class(“骰子”)和“get_player_names”method

    从错误消息中,如果您尝试从错误的位置访问。 您需要先实例化您的 Dice 类才能访问它的方法。

    例如,在您的 GameTest 中,您可以:

    def test_get_player_names(self):
        """Players can enter their names"""
    
        fake_input = mock.Mock(side_effect=['A', 'M', 'Z', ''])
    
        # Create a Dice Instance
        dice_game = game.Dice()
    
        with mock.patch('builtins.input', fake_input):
            names = dice_game.get_player_names()  # Reference to the Dice Instance and not the module
    
        self.assertEqual(names, ['A', 'M', 'Z'])
    

    【讨论】:

    • 我试过了,但它抛出了一个 TypeError: get_player_names() 接受 0 个位置参数,但给出了 1 个
    • 啊,当然...我错过了,您在该定义中缺少self 参数(您可能想要这样,以便您也可以将输入保存在实例中)。
    猜你喜欢
    • 2020-12-04
    • 1970-01-01
    • 2023-03-26
    • 2014-10-23
    • 2022-06-10
    • 2018-04-14
    • 2019-02-18
    • 1970-01-01
    • 2017-08-01
    相关资源
    最近更新 更多