Reputation: 3973
If I have a unittest.TestCase
, I try to patch sys.stdin
on the function itself:
@patch('sys.stdin', new_callable=StringIO)
def test_bla(mocked_stdin):
mocked_stdin.write("TEST")
a = MyClass()
a.do_stuff_with_stdin()
Weirdly enough then if we try to access sys.stdin
from that class, the string we just wrote is not there to be read:
import sys
def do_stuff_with_stdin():
r = sys.stdin.read()
# r = ""
But sys.stdin
has been replaced with a StringIO instance. So the mocking has worked, it's just that the contents are empty.
I am running these tests using pytest
.
Upvotes: 1
Views: 573
Reputation: 3973
After writing this down, I figured out one solution, but I'm not sure exactly why this works.
I move the patch into the class and instantiate StringIO
directly with the data that's supposed to be in there:
with patch('sys.stdin', StringIO(data)):
a = MyClass()
a.do_stuff_with_stdin()
This seems to work, but I'm a bit flummoxed why that is the case.
Update: I get why this works (thanks to @hoefling's comment as well), because in this case the StringIO is initialised with a buffer but: “In both cases, the initial file position starts at zero.”
Upvotes: 1