Skip to content

Commit 5777369

Browse files
committed
Combine and refine dependency injection patterns
1 parent e0e9bfc commit 5777369

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed

patterns/dependency_injection.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#!/usr/bin/python
2+
# -*- coding : utf-8 -*-
3+
4+
"""
5+
Port of the Java example of "Constructor Injection" in
6+
"xUnit Test Patterns - Refactoring Test Code" by Gerard Meszaros
7+
(ISBN-10: 0131495054, ISBN-13: 978-0131495050)
8+
9+
production code which is untestable:
10+
11+
class TimeDisplay(object):
12+
13+
def __init__(self):
14+
self.time_provider = datetime.datetime
15+
16+
def get_current_time_as_html_fragment(self):
17+
current_time = self.time_provider.now()
18+
current_time_as_html_fragment = "<span class=\"tinyBoldText\">{}</span>".format(current_time)
19+
return current_time_as_html_fragment
20+
"""
21+
22+
import datetime
23+
24+
25+
class ConstructorInjection(object):
26+
27+
def __init__(self, time_provider):
28+
self.time_provider = time_provider
29+
30+
def get_current_time_as_html_fragment(self):
31+
current_time = self.time_provider()
32+
current_time_as_html_fragment = "<span class=\"tinyBoldText\">{}</span>".format(current_time)
33+
return current_time_as_html_fragment
34+
35+
36+
class ParameterInjection(object):
37+
38+
def __init__(self):
39+
pass
40+
41+
def get_current_time_as_html_fragment(self, time_provider):
42+
current_time = time_provider()
43+
current_time_as_html_fragment = "<span class=\"tinyBoldText\">{}</span>".format(current_time)
44+
return current_time_as_html_fragment
45+
46+
47+
class SetterInjection(object):
48+
"""Setter Injection"""
49+
50+
def __init__(self):
51+
pass
52+
53+
def set_time_provider(self, time_provider):
54+
self.time_provider = time_provider
55+
56+
def get_current_time_as_html_fragment(self):
57+
current_time = self.time_provider()
58+
current_time_as_html_fragment = "<span class=\"tinyBoldText\">{}</span>".format(current_time)
59+
return current_time_as_html_fragment
60+
61+
62+
def production_code_time_provider():
63+
"""
64+
Production code version of the time provider (just a wrapper for formatting
65+
datetime for this example).
66+
"""
67+
current_time = datetime.datetime.now()
68+
current_time_formatted = "{}:{}".format(current_time.hour, current_time.minute)
69+
return current_time_formatted
70+
71+
72+
def midnight_time_provider():
73+
"""Hard-coded stub"""
74+
return "24:01"
75+
76+
77+
def main():
78+
"""
79+
>>> time_with_ci1 = ConstructorInjection(midnight_time_provider)
80+
>>> time_with_ci1.get_current_time_as_html_fragment()
81+
'<span class="tinyBoldText">24:01</span>'
82+
83+
>>> time_with_ci2 = ConstructorInjection(production_code_time_provider)
84+
>>> time_with_ci2.get_current_time_as_html_fragment()
85+
'<span class="tinyBoldText">...</span>'
86+
87+
>>> time_with_pi = ParameterInjection()
88+
>>> time_with_pi.get_current_time_as_html_fragment(midnight_time_provider)
89+
'<span class="tinyBoldText">24:01</span>'
90+
91+
>>> time_with_si = SetterInjection()
92+
93+
# >>> time_with_si.get_current_time_as_html_fragment()
94+
# AttributeError: 'SetterInjection' object has no attribute 'time_provider'
95+
96+
>>> time_with_si.set_time_provider(midnight_time_provider)
97+
>>> time_with_si.get_current_time_as_html_fragment()
98+
'<span class="tinyBoldText">24:01</span>'
99+
"""
100+
101+
102+
if __name__ == "__main__":
103+
import doctest
104+
doctest.testmod(optionflags=doctest.ELLIPSIS)

0 commit comments

Comments
 (0)