Reputation: 229
The function below opens and loads a Json file. My question is whats the best approach to test it?
def read_file_data(filename, path):
os.chdir(path)
with open(filename, encoding="utf8") as data_file:
json_data = json.load(data_file)
return json_data
filename
and path
are passed in as sys.argv's.
I figured that i would need sample data in my test case for a start but not sure how i would actually use it to test the function
class TestMyFunctions(unittest.TestCase):
def test_read_file_data(self):
sample_json = {
'name' : 'John',
'shares' : 100,
'price' : 1230.23
}
Any pointer will be appreciated.
Upvotes: 4
Views: 15054
Reputation: 311
Check these answers first: How to use mock_open with json.load()?
some of the answers are using json.dump
instead of json.dumps
interchagebly, which is wrong.
read, open, load, as stated are from Standard Python Library, already been tested, so you'd rather think about testing some actual column's values/types or some rows in your json file instead, and if you did that, this would not be a unit test anymore, it'll be an integration test since you have dependencies coupled to your method (json data in this case) which would be meaningless to purposely decouple them via mocking.
Upvotes: 0
Reputation: 336
As stated above you do not need to retest the standard python library code works correctly, so by creating a hard coded file as also stated, you are defeating the point of a unit test by testing outside of your unit of code.
Instead a correct approach would be to mock the opening of the file using pythons mocking framework. And thus test that your function returns the json that's read in correctly.
e.g.
from unittest.mock import patch, mock_open
import json
class TestMyFunctions(unittest.TestCase):
@patch("builtins.open", new_callable=mock_open,
read_data=json.dumps({'name' : 'John','shares' : 100,
'price' : 1230.23}))
def test_read_file_data(self):
expected_output = {
'name' : 'John',
'shares' : 100,
'price' : 1230.23
}
filename = 'example.json'
actual_output = read_file_data(filename, 'example/path')
# Assert filename is file that is opened
mock_file.assert_called_with(filename)
self.assertEqual(expected_output, actual_output)
Upvotes: 5
Reputation: 662
I think that what you would want to do would be to make the JSON file, hardcode an in memory version of that JSON file and assert equals between the two.
Based on your code:
class TestMyFunctions(unittest.TestCase):
def test_read_file_data(self):
import json
sample_json = {
'name' : 'John',
'shares' : 100,
'price' : 1230.23
}
sample_json = json.dump(sample_json, ensure_ascii=False)
path = /path/to/file
filename = testcase.json
self.assertEqual(read_file_data(filename, path), sample_json)
Upvotes: 1