I have a function that opens a file within a context manager and then passes its handler to a method of an object.
with open("somefile.txt", "rb") as f:
some_obj.upload(file=f)
My question is how can I unit test pass that f handler? I would like to create a mock open and a mock of some_obj.upload, and check that the file parameter was actually given f.
Currently, I have something like this:
def upload_local_file(local_file: str):
my_obj = SOMEOBJ()
with open(local_file, "rb") as f:
my_obj.upload(file=f)
@mock.patch("some_obj")
@mock.patch("builtins.open")
def test_upload_local_file_positive(mock_open, mock_obj):
f = mock_open.return_value
f.return_value = "/tmp/example_file.txt"
upload_local_file(local_file="/tmp/example_file.txt")
mock_open.assert_called_once_with("/tmp/example_file.txt", "rb")
mock_obj.return_value.upload.assert_called_once_with(
path="/tmp/example_file.txt",
file=f
)
For some reason, it's failing because the file differs in some ways I don't understand, please help me fix this unit test
> mock_obj.return_value.upload.assert_called_once_with(
path="/tmp/example_file.txt",
file=f
)
E AssertionError: expected call not found.
E Expected: upload(path='/tmp/example_file.txt', file=<MagicMock name='open()' id='4432144032'>)
E Actual: upload(file=<MagicMock name='open().__enter__()' id='4432212560'>)
E
E pytest introspection follows:
E
E Kwargs:
E assert {'file': <MagicMock name='open().__enter__()' id='4432212560'>} == {'file': <MagicMock name='open()' id='4432144032'>,\n 'path': '/tmp/example_file.txt'}
E Differing items:
E {'file': <MagicMock name='open().__enter__()' id='4432212560'>} != {'file': <MagicMock name='open()' id='4432144032'>}
E Right contains 1 more item:
E {'path': '/tmp/example_file.txt'}
E Full diff:
E {
E - 'file': <MagicMock name='open()' id='4432144032'>,
E ? ^^ --
E + 'file': <MagicMock name='open().__enter__()' id='4432212560'>,
E ? ++++++++++++ + ^^^
E - 'path': '/tmp/example_file.txt',
E }