-
Notifications
You must be signed in to change notification settings - Fork 106
/
test_base_model.py
executable file
·162 lines (147 loc) · 6.1 KB
/
test_base_model.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!/usr/bin/python3
"""Test BaseModel for expected behavior and documentation"""
from datetime import datetime
import inspect
import models
import os
import pep8 as pycodestyle
import time
import unittest
from unittest import mock
BaseModel = models.base_model.BaseModel
module_doc = models.base_model.__doc__
class TestBaseModelDocs(unittest.TestCase):
"""Tests to check the documentation and style of BaseModel class"""
@classmethod
def setUpClass(self):
"""Set up for docstring tests"""
self.base_funcs = inspect.getmembers(BaseModel, inspect.isfunction)
def test_pep8_conformance(self):
"""Test that models/base_model.py conforms to PEP8."""
for path in ['models/base_model.py',
'tests/test_models/test_base_model.py']:
with self.subTest(path=path):
errors = pycodestyle.Checker(path).check_all()
self.assertEqual(errors, 0)
def test_module_docstring(self):
"""Test for the existence of module docstring"""
self.assertIsNot(module_doc, None,
"base_model.py needs a docstring")
self.assertTrue(len(module_doc) > 1,
"base_model.py needs a docstring")
def test_class_docstring(self):
"""Test for the BaseModel class docstring"""
self.assertIsNot(BaseModel.__doc__, None,
"BaseModel class needs a docstring")
self.assertTrue(len(BaseModel.__doc__) >= 1,
"BaseModel class needs a docstring")
def test_func_docstrings(self):
"""Test for the presence of docstrings in BaseModel methods"""
for func in self.base_funcs:
with self.subTest(function=func):
self.assertIsNot(
func[1].__doc__,
None,
"{:s} method needs a docstring".format(func[0])
)
self.assertTrue(
len(func[1].__doc__) > 1,
"{:s} method needs a docstring".format(func[0])
)
class TestBaseModel(unittest.TestCase):
"""Test the BaseModel class"""
def test_instantiation(self):
"""Test that object is correctly created"""
inst = BaseModel()
self.assertIs(type(inst), BaseModel)
inst.name = "Holberton"
inst.number = 89
attrs_types = {
"id": str,
"created_at": datetime,
"updated_at": datetime,
"name": str,
"number": int
}
for attr, typ in attrs_types.items():
with self.subTest(attr=attr, typ=typ):
self.assertIn(attr, inst.__dict__)
self.assertIs(type(inst.__dict__[attr]), typ)
self.assertEqual(inst.name, "Holberton")
self.assertEqual(inst.number, 89)
def test_datetime_attributes(self):
"""Test that two BaseModel instances have different datetime objects
and that upon creation have identical updated_at and created_at
value."""
tic = datetime.now()
inst1 = BaseModel()
toc = datetime.now()
self.assertTrue(tic <= inst1.created_at <= toc)
time.sleep(1e-4)
tic = datetime.now()
inst2 = BaseModel()
toc = datetime.now()
self.assertTrue(tic <= inst2.created_at <= toc)
self.assertEqual(inst1.created_at, inst1.updated_at)
self.assertEqual(inst2.created_at, inst2.updated_at)
self.assertNotEqual(inst1.created_at, inst2.created_at)
self.assertNotEqual(inst1.updated_at, inst2.updated_at)
def test_uuid(self):
"""Test that id is a valid uuid"""
inst1 = BaseModel()
inst2 = BaseModel()
for inst in [inst1, inst2]:
uuid = inst.id
with self.subTest(uuid=uuid):
self.assertIs(type(uuid), str)
self.assertRegex(uuid,
'^[0-9a-f]{8}-[0-9a-f]{4}'
'-[0-9a-f]{4}-[0-9a-f]{4}'
'-[0-9a-f]{12}$')
self.assertNotEqual(inst1.id, inst2.id)
def test_to_dict(self):
"""Test conversion of object attributes to dictionary for json"""
my_model = BaseModel()
my_model.name = "Holberton"
my_model.my_number = 89
d = my_model.to_dict()
expected_attrs = ["id",
"created_at",
"updated_at",
"name",
"my_number",
"__class__"]
self.assertCountEqual(d.keys(), expected_attrs)
self.assertEqual(d['__class__'], 'BaseModel')
self.assertEqual(d['name'], "Holberton")
self.assertEqual(d['my_number'], 89)
self.assertNotIn('_sa_instance_state', d)
def test_to_dict_values(self):
"""test that values in dict returned from to_dict are correct"""
t_format = "%Y-%m-%dT%H:%M:%S.%f"
bm = BaseModel()
new_d = bm.to_dict()
self.assertEqual(new_d["__class__"], "BaseModel")
self.assertEqual(type(new_d["created_at"]), str)
self.assertEqual(type(new_d["updated_at"]), str)
self.assertEqual(new_d["created_at"], bm.created_at.strftime(t_format))
self.assertEqual(new_d["updated_at"], bm.updated_at.strftime(t_format))
def test_str(self):
"""test that the str method has the correct output"""
inst = BaseModel()
string = "[BaseModel] ({}) {}".format(inst.id, inst.__dict__)
self.assertEqual(string, str(inst))
@mock.patch('models.storage')
def test_save(self, mock_storage):
"""Test that save method updates `updated_at` and calls
`storage.save`"""
inst = BaseModel()
old_created_at = inst.created_at
old_updated_at = inst.updated_at
inst.save()
new_created_at = inst.created_at
new_updated_at = inst.updated_at
self.assertNotEqual(old_updated_at, new_updated_at)
self.assertEqual(old_created_at, new_created_at)
self.assertTrue(mock_storage.new.called)
self.assertTrue(mock_storage.save.called)