Arne
Arne

Reputation: 20117

How to test click commands that expect files

I have a click command that does something with a file:

import click

@click.command()
@click.argument("file", type=click.File("r"))
def foo(file):
    print(file.read())

And I'd like to test it without creating temporary files, but I don't know which path to give the runner and can't find examples on the web. Something like this would be nice:

from click.testing import CliRunner

from magic_lib import magic_file

def test_foo():
    runner = CliRunner()
    fake_file = magic_file("Hello, world!")
    result = runner.invoke(foo, [fake_file.location])
    assert result.output == "Hello, world!\n"

Any way I can make click.File understand where I want it to look?

Upvotes: 1

Views: 635

Answers (1)

Aran-Fey
Aran-Fey

Reputation: 43126

You can use pyfakefs. The usage depends on your testing framework; it's easiest to use with pytest because it automatically provides an fs fixture:

def test_foo(fs):
    fake_file = fs.create_file('/foo/bar', contents="Hello, world!")

    runner = CliRunner()
    result = runner.invoke(foo, [fake_file.path])
    assert result.output == "Hello, world!\n"

P.S.: Because the print in foo adds a newline, the file has to be created without \n at the end for the test to work.

Upvotes: 1

Related Questions