python - AttributeError: 'NoneType' 对象没有属性 '_with_attr' - Python 使用 pytest 运行测试

标签 python pytest attributeerror smartcontracts

我的环境是: python 3.9.9 测试 6.2.5 布朗尼 1.17.1

我正在研究 Youtube 上 Patrick Collins 的智能合约教程中的 test_fund_me.py;在这个阶段,我应该运行测试并通过 Pytest 包含一个异常,这样只有合约的所有者才能调用该函数。我添加了 pytest.raises(exceptions.VirtualMachineError) 方法,但它仍然返回失败的测试并引发标题中提到的错误。

这是我的代码:

from scripts.helpful_scripts import get_account, LOCAL_BLOCKCHAIN_ENVIRONMENTS
from scripts.deploy import deploy_fund_me
from brownie import network, accounts, exceptions
import pytest


def test_can_fund_and_withdraw():
    account = get_account()
    fund_me = deploy_fund_me()
    entrance_fee = fund_me.getEntranceFee() + 100
    tx = fund_me.fund({"from": account, "value": entrance_fee})
    tx.wait(1)
    assert fund_me.addressToAmountFunded(account.address) == entrance_fee
    tx2 = fund_me.withdraw({"from": account})
    tx2.wait(1)
    assert fund_me.addressToAmountFunded(account.address) == 0


def test_only_owner_can_withdraw():
    if network.show_active() not in LOCAL_BLOCKCHAIN_ENVIRONMENTS:
        pytest.skip("only for local testing")
    fund_me = deploy_fund_me()
    bad_actor = accounts.add()
    with pytest.raises(exceptions.VirtualMachineError):
        fund_me.withdraw({"from": bad_actor})

这是错误信息:

PS C:\Users\chret\Documents\demo\brownie_fund_me> brownie test -k test_only_owner_can_withdraw
INFO: Could not find files for the given pattern(s).
Brownie v1.17.1 - Python development framework for Ethereum

=============================================================================== test session starts ================================================================================
platform win32 -- Python 3.9.9, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: C:\Users\chret\Documents\demo\brownie_fund_me
plugins: eth-brownie-1.17.1, hypothesis-6.24.0, forked-1.3.0, xdist-1.34.0, web3-5.24.0
collected 2 items / 1 deselected / 1 selected                                                                                                                                       

Launching 'ganache-cli.cmd --accounts 10 --hardfork istanbul --gasLimit 12000000 --mnemonic brownie --port 8545'...

tests\test_fund_me.py F                                                                                                                                                       [100%]

===================================================================================== FAILURES =====================================================================================
___________________________________________________________________________ test_only_owner_can_withdraw ___________________________________________________________________________

    def test_only_owner_can_withdraw():
        if network.show_active() not in LOCAL_BLOCKCHAIN_ENVIRONMENTS:
            pytest.skip("only for local testing")
        fund_me = deploy_fund_me()
        bad_actor = accounts.add()
        with pytest.raises(exceptions.VirtualMachineError):
>           fund_me.withdraw({"from": bad_actor})

tests\test_fund_me.py:25:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
..\..\..\AppData\Local\Programs\Python\Python39\lib\site-packages\brownie\network\contract.py:1625: in __call__
    return self.transact(*args)
..\..\..\AppData\Local\Programs\Python\Python39\lib\site-packages\brownie\network\contract.py:1498: in transact
    return tx["from"].transfer(
..\..\..\AppData\Local\Programs\Python\Python39\lib\site-packages\brownie\network\account.py:690: in transfer
    receipt._raise_if_reverted(exc)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <Transaction '0xb66de8420866ddd8efba108a2b401d80a64cbdeb780ea09ef75a73185809bbca'>, exc = None

    def _raise_if_reverted(self, exc: Any) -> None:
        if self.status or CONFIG.mode == "console":
            return
        if not web3.supports_traces:
            # if traces are not available, do not attempt to determine the revert reason
            raise exc or ValueError("Execution reverted")

        if self._dev_revert_msg is None:
            # no revert message and unable to check dev string - have to get trace
            self._expand_trace()
        if self.contract_address:
            source = ""
        elif CONFIG.argv["revert"]:
            source = self._traceback_string()
        else:
            source = self._error_string(1)
            contract = state._find_contract(self.receiver)
            if contract:
                marker = "//" if contract._build["language"] == "Solidity" else "#"
                line = self._traceback_string().split("\n")[-1]
                if marker + " dev: " in line:
                    self._dev_revert_msg = line[line.index(marker) + len(marker) : -5].strip()

>       raise exc._with_attr(
            source=source, revert_msg=self._revert_msg, dev_revert_msg=self._dev_revert_msg
        )
E       AttributeError: 'NoneType' object has no attribute '_with_attr'

..\..\..\AppData\Local\Programs\Python\Python39\lib\site-packages\brownie\network\transaction.py:446: AttributeError
------------------------------------------------------------------------------- Captured stdout call -------------------------------------------------------------------------------
The active network is development
Deploying Mocks...
Mocks Deployed!
Contract deployed to 0x602C71e4DAC47a042Ee7f46E0aee17F94A3bA0B6
mnemonic: 'veteran company dinosaur actual jump club quit horn walk gym jar melody'
============================================================================= short test summary info ==============================================================================
FAILED tests/test_fund_me.py::test_only_owner_can_withdraw - AttributeError: 'NoneType' object has no attribute '_with_attr'
========================================================================= 1 failed, 1 deselected in 4.70s ==========================================================================
Terminating local RPC client...
PS C:\Users\chret\Documents\demo\brownie_fund_me>

我查过这个“NoneType”错误是什么,据我了解,它可能来自帐户的 bad_actor 调用,它看起来像 bad_actor = account.add() 返回一种无类型。但我不确定,我也不明白如何解决这个问题。

几天前我看到有人就同一件事提出了一个问题,关闭终端后问题就消失了。那不是我的情况,我什至重新启动了计算机,问题仍然存在。

感谢任何帮助:)

最佳答案

我遇到了同样的问题,如果我更改了我传递给 pytest.raises() 的内容,我就能让它工作:

使用 pytest.raises(AttributeError):

关于python - AttributeError: 'NoneType' 对象没有属性 '_with_attr' - Python 使用 pytest 运行测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70242806/

相关文章:

Python解析xml并构建数据框

python - 检查冲突/学生不能在同一类(class)中注册两次

python - 不能将 attach_mock 与 autospec 函数模拟一起使用

python - 我将如何在 python 中发送电子邮件?此代码无效

python-2.7 - 为什么会出现 AttributeError : 'Response' object has no attribute 'get' in Python2. 7 错误?

python - Python 的 PCRE 正则表达式 (*COMMIT) 等效项

python - 不在特定环境下导出conda环境

python - 如何使用 pytest 测试无限 while 循环

python - Pytest - 测试后如何查找测试结果

python - 另一个 "instance has no attribute ' __getitem_ _' "案例