Alper
Alper

Reputation: 3973

Patched stdin in unittest does not have the string written into it

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

Answers (1)

Alper
Alper

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

Related Questions