为什么 monkeypatch 无法识别构造函数中的赋值?
Why does monkeypatch not recognize an assignment value in the constructor?
我正在练习 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()
测试运行成功。
为什么构造函数中的赋值不起作用?
我想到了这个解决方案。我正在使用图书馆的 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
更新: 为了演示目的,我再次将流 (stdin) 包含到构造函数中。这样我就可以编写第二个方法并传递一个文件描述符。
我正在练习 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()
测试运行成功。
为什么构造函数中的赋值不起作用?
我想到了这个解决方案。我正在使用图书馆的 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
更新: 为了演示目的,我再次将流 (stdin) 包含到构造函数中。这样我就可以编写第二个方法并传递一个文件描述符。