Python 3 Context Manager Mock Unit Test
I have the following bit of code.
import yaml
def load_yaml_file(filename):
with open(filename, 'rt') as f:
data = yaml.load(f)
return data
Is there a way to mock the open
part so that f becomes '"hello":"world"'
and thus I can assert that data is properly returned.
I tried to mock open with mock_open.return_value.__enter__.return_value = '"hello":"world"'
and couldn't get it to work properly.
I'm using pytest and mocker.
python-3.x unit-testing mocking pytest
add a comment |
I have the following bit of code.
import yaml
def load_yaml_file(filename):
with open(filename, 'rt') as f:
data = yaml.load(f)
return data
Is there a way to mock the open
part so that f becomes '"hello":"world"'
and thus I can assert that data is properly returned.
I tried to mock open with mock_open.return_value.__enter__.return_value = '"hello":"world"'
and couldn't get it to work properly.
I'm using pytest and mocker.
python-3.x unit-testing mocking pytest
Nothing to do with your question, but are you sure you needyaml.load()
and thatyaml.safe_load()
wouldn't do the job? Even if you need to load specific objects from the standard Python library, it is better to register those explicitly for safe_loading, than to use the potentially unsafeload()
– Anthon
Nov 24 '18 at 20:06
Anthon - Very very good point, thank you for pointing that out!
– ClickThisNick
Nov 26 '18 at 14:40
add a comment |
I have the following bit of code.
import yaml
def load_yaml_file(filename):
with open(filename, 'rt') as f:
data = yaml.load(f)
return data
Is there a way to mock the open
part so that f becomes '"hello":"world"'
and thus I can assert that data is properly returned.
I tried to mock open with mock_open.return_value.__enter__.return_value = '"hello":"world"'
and couldn't get it to work properly.
I'm using pytest and mocker.
python-3.x unit-testing mocking pytest
I have the following bit of code.
import yaml
def load_yaml_file(filename):
with open(filename, 'rt') as f:
data = yaml.load(f)
return data
Is there a way to mock the open
part so that f becomes '"hello":"world"'
and thus I can assert that data is properly returned.
I tried to mock open with mock_open.return_value.__enter__.return_value = '"hello":"world"'
and couldn't get it to work properly.
I'm using pytest and mocker.
python-3.x unit-testing mocking pytest
python-3.x unit-testing mocking pytest
asked Nov 13 '18 at 14:06
ClickThisNickClickThisNick
2,02182448
2,02182448
Nothing to do with your question, but are you sure you needyaml.load()
and thatyaml.safe_load()
wouldn't do the job? Even if you need to load specific objects from the standard Python library, it is better to register those explicitly for safe_loading, than to use the potentially unsafeload()
– Anthon
Nov 24 '18 at 20:06
Anthon - Very very good point, thank you for pointing that out!
– ClickThisNick
Nov 26 '18 at 14:40
add a comment |
Nothing to do with your question, but are you sure you needyaml.load()
and thatyaml.safe_load()
wouldn't do the job? Even if you need to load specific objects from the standard Python library, it is better to register those explicitly for safe_loading, than to use the potentially unsafeload()
– Anthon
Nov 24 '18 at 20:06
Anthon - Very very good point, thank you for pointing that out!
– ClickThisNick
Nov 26 '18 at 14:40
Nothing to do with your question, but are you sure you need
yaml.load()
and that yaml.safe_load()
wouldn't do the job? Even if you need to load specific objects from the standard Python library, it is better to register those explicitly for safe_loading, than to use the potentially unsafe load()
– Anthon
Nov 24 '18 at 20:06
Nothing to do with your question, but are you sure you need
yaml.load()
and that yaml.safe_load()
wouldn't do the job? Even if you need to load specific objects from the standard Python library, it is better to register those explicitly for safe_loading, than to use the potentially unsafe load()
– Anthon
Nov 24 '18 at 20:06
Anthon - Very very good point, thank you for pointing that out!
– ClickThisNick
Nov 26 '18 at 14:40
Anthon - Very very good point, thank you for pointing that out!
– ClickThisNick
Nov 26 '18 at 14:40
add a comment |
2 Answers
2
active
oldest
votes
DISCLAIMERS
- This solution does not use Mocker, but can be used with pytest.
- This solution works for Python >= 3.6
As you said you are using Mocker, I will assume that you are working on a very old codebase (<= 2.6). I highly recommend you port you code to any version >= 3.6
Since Python 3.3 mock is integrated to standard lib in unittest.mock and is a pretty much clone from old mock package
The mock lib has a feature called mock_open that does exactly what you need and has an example with exactly what you want.
with patch('__main__.open', mock_open(read_data='bibble')) as m:
with open('foo') as h:
result = h.read()
m.assert_called_once_with('foo')
assert result == 'bibble'
Adapting the solution to your need you can use this example
import yaml
from unittest.mock import patch, mock_open
def load_yaml_file(filename):
with open(filename, 'rt') as f:
data = yaml.load(f)
return data
with patch('__main__.open', mock_open(read_data='"hello":"world"')) as m:
res = load_yaml_file('foo')
assert res == "hello":"world"
add a comment |
You don't need to set __enter__
at all. Just pass in the data you want read as the read_data
argument to mock_open()
:
mocked_open = mock.mock_open(read_data='"hello":"world"')
with mock.patch("yourmodule.open", mocked_open):
result = load_yaml_file("foobar.yaml")
Demonstration:
>>> import yaml
>>> def load_yaml_file(filename):
... with open(filename, 'rt') as f:
... data = yaml.load(f)
... return data
...
>>> from unittest import mock
>>> mocked_open = mock.mock_open(read_data='"hello":"world"')
>>> with mock.patch("__main__.open", mocked_open):
... result = load_yaml_file("foobar.yaml")
...
>>> print(result)
'hello': 'world'
>>> mocked_open.mock_calls
[call('foobar.yaml', 'rt'),
call().__enter__(),
call().read(4096),
call().read(4096),
call().__exit__(None, None, None)]
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53282809%2fpython-3-context-manager-mock-unit-test%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
DISCLAIMERS
- This solution does not use Mocker, but can be used with pytest.
- This solution works for Python >= 3.6
As you said you are using Mocker, I will assume that you are working on a very old codebase (<= 2.6). I highly recommend you port you code to any version >= 3.6
Since Python 3.3 mock is integrated to standard lib in unittest.mock and is a pretty much clone from old mock package
The mock lib has a feature called mock_open that does exactly what you need and has an example with exactly what you want.
with patch('__main__.open', mock_open(read_data='bibble')) as m:
with open('foo') as h:
result = h.read()
m.assert_called_once_with('foo')
assert result == 'bibble'
Adapting the solution to your need you can use this example
import yaml
from unittest.mock import patch, mock_open
def load_yaml_file(filename):
with open(filename, 'rt') as f:
data = yaml.load(f)
return data
with patch('__main__.open', mock_open(read_data='"hello":"world"')) as m:
res = load_yaml_file('foo')
assert res == "hello":"world"
add a comment |
DISCLAIMERS
- This solution does not use Mocker, but can be used with pytest.
- This solution works for Python >= 3.6
As you said you are using Mocker, I will assume that you are working on a very old codebase (<= 2.6). I highly recommend you port you code to any version >= 3.6
Since Python 3.3 mock is integrated to standard lib in unittest.mock and is a pretty much clone from old mock package
The mock lib has a feature called mock_open that does exactly what you need and has an example with exactly what you want.
with patch('__main__.open', mock_open(read_data='bibble')) as m:
with open('foo') as h:
result = h.read()
m.assert_called_once_with('foo')
assert result == 'bibble'
Adapting the solution to your need you can use this example
import yaml
from unittest.mock import patch, mock_open
def load_yaml_file(filename):
with open(filename, 'rt') as f:
data = yaml.load(f)
return data
with patch('__main__.open', mock_open(read_data='"hello":"world"')) as m:
res = load_yaml_file('foo')
assert res == "hello":"world"
add a comment |
DISCLAIMERS
- This solution does not use Mocker, but can be used with pytest.
- This solution works for Python >= 3.6
As you said you are using Mocker, I will assume that you are working on a very old codebase (<= 2.6). I highly recommend you port you code to any version >= 3.6
Since Python 3.3 mock is integrated to standard lib in unittest.mock and is a pretty much clone from old mock package
The mock lib has a feature called mock_open that does exactly what you need and has an example with exactly what you want.
with patch('__main__.open', mock_open(read_data='bibble')) as m:
with open('foo') as h:
result = h.read()
m.assert_called_once_with('foo')
assert result == 'bibble'
Adapting the solution to your need you can use this example
import yaml
from unittest.mock import patch, mock_open
def load_yaml_file(filename):
with open(filename, 'rt') as f:
data = yaml.load(f)
return data
with patch('__main__.open', mock_open(read_data='"hello":"world"')) as m:
res = load_yaml_file('foo')
assert res == "hello":"world"
DISCLAIMERS
- This solution does not use Mocker, but can be used with pytest.
- This solution works for Python >= 3.6
As you said you are using Mocker, I will assume that you are working on a very old codebase (<= 2.6). I highly recommend you port you code to any version >= 3.6
Since Python 3.3 mock is integrated to standard lib in unittest.mock and is a pretty much clone from old mock package
The mock lib has a feature called mock_open that does exactly what you need and has an example with exactly what you want.
with patch('__main__.open', mock_open(read_data='bibble')) as m:
with open('foo') as h:
result = h.read()
m.assert_called_once_with('foo')
assert result == 'bibble'
Adapting the solution to your need you can use this example
import yaml
from unittest.mock import patch, mock_open
def load_yaml_file(filename):
with open(filename, 'rt') as f:
data = yaml.load(f)
return data
with patch('__main__.open', mock_open(read_data='"hello":"world"')) as m:
res = load_yaml_file('foo')
assert res == "hello":"world"
answered Nov 24 '18 at 4:42
Mauro BaraldiMauro Baraldi
3,92112031
3,92112031
add a comment |
add a comment |
You don't need to set __enter__
at all. Just pass in the data you want read as the read_data
argument to mock_open()
:
mocked_open = mock.mock_open(read_data='"hello":"world"')
with mock.patch("yourmodule.open", mocked_open):
result = load_yaml_file("foobar.yaml")
Demonstration:
>>> import yaml
>>> def load_yaml_file(filename):
... with open(filename, 'rt') as f:
... data = yaml.load(f)
... return data
...
>>> from unittest import mock
>>> mocked_open = mock.mock_open(read_data='"hello":"world"')
>>> with mock.patch("__main__.open", mocked_open):
... result = load_yaml_file("foobar.yaml")
...
>>> print(result)
'hello': 'world'
>>> mocked_open.mock_calls
[call('foobar.yaml', 'rt'),
call().__enter__(),
call().read(4096),
call().read(4096),
call().__exit__(None, None, None)]
add a comment |
You don't need to set __enter__
at all. Just pass in the data you want read as the read_data
argument to mock_open()
:
mocked_open = mock.mock_open(read_data='"hello":"world"')
with mock.patch("yourmodule.open", mocked_open):
result = load_yaml_file("foobar.yaml")
Demonstration:
>>> import yaml
>>> def load_yaml_file(filename):
... with open(filename, 'rt') as f:
... data = yaml.load(f)
... return data
...
>>> from unittest import mock
>>> mocked_open = mock.mock_open(read_data='"hello":"world"')
>>> with mock.patch("__main__.open", mocked_open):
... result = load_yaml_file("foobar.yaml")
...
>>> print(result)
'hello': 'world'
>>> mocked_open.mock_calls
[call('foobar.yaml', 'rt'),
call().__enter__(),
call().read(4096),
call().read(4096),
call().__exit__(None, None, None)]
add a comment |
You don't need to set __enter__
at all. Just pass in the data you want read as the read_data
argument to mock_open()
:
mocked_open = mock.mock_open(read_data='"hello":"world"')
with mock.patch("yourmodule.open", mocked_open):
result = load_yaml_file("foobar.yaml")
Demonstration:
>>> import yaml
>>> def load_yaml_file(filename):
... with open(filename, 'rt') as f:
... data = yaml.load(f)
... return data
...
>>> from unittest import mock
>>> mocked_open = mock.mock_open(read_data='"hello":"world"')
>>> with mock.patch("__main__.open", mocked_open):
... result = load_yaml_file("foobar.yaml")
...
>>> print(result)
'hello': 'world'
>>> mocked_open.mock_calls
[call('foobar.yaml', 'rt'),
call().__enter__(),
call().read(4096),
call().read(4096),
call().__exit__(None, None, None)]
You don't need to set __enter__
at all. Just pass in the data you want read as the read_data
argument to mock_open()
:
mocked_open = mock.mock_open(read_data='"hello":"world"')
with mock.patch("yourmodule.open", mocked_open):
result = load_yaml_file("foobar.yaml")
Demonstration:
>>> import yaml
>>> def load_yaml_file(filename):
... with open(filename, 'rt') as f:
... data = yaml.load(f)
... return data
...
>>> from unittest import mock
>>> mocked_open = mock.mock_open(read_data='"hello":"world"')
>>> with mock.patch("__main__.open", mocked_open):
... result = load_yaml_file("foobar.yaml")
...
>>> print(result)
'hello': 'world'
>>> mocked_open.mock_calls
[call('foobar.yaml', 'rt'),
call().__enter__(),
call().read(4096),
call().read(4096),
call().__exit__(None, None, None)]
answered Nov 25 '18 at 11:57
Martijn Pieters♦Martijn Pieters
705k13324552281
705k13324552281
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53282809%2fpython-3-context-manager-mock-unit-test%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Nothing to do with your question, but are you sure you need
yaml.load()
and thatyaml.safe_load()
wouldn't do the job? Even if you need to load specific objects from the standard Python library, it is better to register those explicitly for safe_loading, than to use the potentially unsafeload()
– Anthon
Nov 24 '18 at 20:06
Anthon - Very very good point, thank you for pointing that out!
– ClickThisNick
Nov 26 '18 at 14:40