为什么Monkeypatch无法在构造函数中识别出赋值?

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

我正在练习TDD,对此我还很陌生。在我的测试案例中,我想从stdin读取并检查输出是否与输入匹配。

对于stdin我想使用一个模拟对象。因此,我使用monkeypatch.setattr('sys.stdin', StringIO(string))stdin替换为StringIO,因为两者都具有方法read()

# XPath.py
import sys
from io import StringIO

class XPath:
    def __init__(self):
        self.stdin = sys.stdin

    def readStdin(self):
        return self.stdin.read()
# TestXPath.py
import pytest
from XPath import XPath
from io import StringIO

def test_CanReadFromStdin(monkeypatch):
    xpath = XPath()
    string = "<a></a>\n"
    monkeypatch.setattr('sys.stdin', StringIO(string))
    assert xpath.readStdin() == string

但是,此操作失败

FAILED                               [100%]
TestXPath.py:4 (test_CanReadFromStdin)
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7f2dafc5ec90>

    def test_CanReadFromStdin(monkeypatch):
        xpath = XPath()
        string = "<a></a>\n"
        monkeypatch.setattr('sys.stdin', StringIO(string))
>       assert xpath.readStdin() == string

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
XPath.py:9: in readStdin
    return self.stdin.read()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

pytest被调用而没有任何标志。添加-s导致永无休止的循环。有趣的是,当我在省略构造函数的同时将XPath.py中的行更改为:

    def readStdin(self):
        return sys.stdin.read()

测试成功运行。

为什么构造函数中的分配不起作用?

python tdd pytest
1个回答
0
投票

我已经提出了这个解决方案。我正在使用库中的Mock()。然后我在构造函数中删除了stdin分配。

#XPath.py
import sys
class XPath:
    def __init__(self, stream):
        self.stream = stream
        pass

    def readStdin(self):
        return self.stream.read()


# test_file.py
import pytest
from XPath import XPath
from io import StringIO

def test_CanReadFromStdin(monkeypatch):
    string = "<a></a>\n"
    from unittest.mock import Mock
    mock_stdin = Mock()
    mock_stdin.readline = Mock(StringIO(string))
    monkeypatch.setattr('sys.stdin', StringIO(string))
    import sys
    xpath = XPath(sys.stdin)
    assert xpath.readStdin() == string

Update:为了演示目的,我再次将流(stdin)包含在构造函数中。这样,我可以编写第二种方法并传递文件描述符。

© www.soinside.com 2019 - 2024. All rights reserved.