-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtest_call_handler.py
177 lines (134 loc) · 5.01 KB
/
test_call_handler.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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
"""Tests for the SpyEvent handling."""
import pytest
from decoy import Decoy
from decoy.call_handler import CallHandler, CallHandlerResult
from decoy.spy_log import SpyLog
from decoy.spy_events import SpyInfo, SpyCall, SpyEvent, SpyPropAccess, PropAccessType
from decoy.stub_store import StubBehavior, StubStore
@pytest.fixture()
def spy_log(decoy: Decoy) -> SpyLog:
"""Get a mock instance of a SpyLog."""
return decoy.mock(cls=SpyLog)
@pytest.fixture()
def stub_store(decoy: Decoy) -> StubStore:
"""Get a mock instance of a StubStore."""
return decoy.mock(cls=StubStore)
@pytest.fixture()
def subject(spy_log: SpyLog, stub_store: StubStore) -> CallHandler:
"""Get a CallHandler instance with its dependencies mocked out."""
return CallHandler(
spy_log=spy_log,
stub_store=stub_store,
)
def test_handle_call_with_no_stubbing(
decoy: Decoy,
spy_log: SpyLog,
stub_store: StubStore,
subject: CallHandler,
) -> None:
"""It should noop and add the call to the stack if no stubbing is configured."""
spy_call = SpyEvent(
spy=SpyInfo(id=42, name="spy_name", is_async=False),
payload=SpyCall(args=(), kwargs={}),
)
behavior = None
decoy.when(stub_store.get_by_call(spy_call)).then_return(behavior)
result = subject.handle(spy_call)
assert result is None
decoy.verify(spy_log.push(spy_call))
def test_handle_call_with_return(
decoy: Decoy,
spy_log: SpyLog,
stub_store: StubStore,
subject: CallHandler,
) -> None:
"""It return a Stub's configured return value."""
spy_call = SpyEvent(
spy=SpyInfo(id=42, name="spy_name", is_async=False),
payload=SpyCall(args=(), kwargs={}),
)
behavior = StubBehavior(return_value="hello world")
decoy.when(stub_store.get_by_call(spy_call)).then_return(behavior)
result = subject.handle(spy_call)
assert result == CallHandlerResult("hello world")
decoy.verify(spy_log.push(spy_call))
def test_handle_call_with_raise(
decoy: Decoy,
spy_log: SpyLog,
stub_store: StubStore,
subject: CallHandler,
) -> None:
"""It raise a Stub's configured error."""
spy_call = SpyEvent(
spy=SpyInfo(id=42, name="spy_name", is_async=False),
payload=SpyCall(args=(), kwargs={}),
)
behavior = StubBehavior(error=RuntimeError("oh no"))
decoy.when(stub_store.get_by_call(spy_call)).then_return(behavior)
with pytest.raises(RuntimeError, match="oh no"):
subject.handle(spy_call)
decoy.verify(spy_log.push(spy_call))
def test_handle_call_with_action(
decoy: Decoy,
stub_store: StubStore,
subject: CallHandler,
) -> None:
"""It should trigger a stub's configured action."""
action = decoy.mock(name="action")
spy_call = SpyEvent(
spy=SpyInfo(id=42, name="spy_name", is_async=False),
payload=SpyCall(args=(1,), kwargs={"foo": "bar"}),
)
behavior = StubBehavior(action=action)
decoy.when(stub_store.get_by_call(spy_call)).then_return(behavior)
decoy.when(action(1, foo="bar")).then_return("hello world")
result = subject.handle(spy_call)
assert result == CallHandlerResult("hello world")
def test_handle_prop_get_with_action(
decoy: Decoy,
stub_store: StubStore,
subject: CallHandler,
) -> None:
"""It should trigger a prop get stub's configured action."""
action = decoy.mock(name="action")
spy_call = SpyEvent(
spy=SpyInfo(id=42, name="spy_name", is_async=False),
payload=SpyPropAccess(prop_name="prop", access_type=PropAccessType.GET),
)
behavior = StubBehavior(action=action)
decoy.when(stub_store.get_by_call(spy_call)).then_return(behavior)
decoy.when(action()).then_return("hello world")
result = subject.handle(spy_call)
assert result == CallHandlerResult("hello world")
def test_handle_call_with_context_enter(
decoy: Decoy,
spy_log: SpyLog,
stub_store: StubStore,
subject: CallHandler,
) -> None:
"""It should return a Stub's configured context value."""
spy_call = SpyEvent(
spy=SpyInfo(id=42, name="spy_name", is_async=False),
payload=SpyCall(args=(), kwargs={}),
)
behavior = StubBehavior(context_value="hello world")
decoy.when(stub_store.get_by_call(spy_call)).then_return(behavior)
with subject.handle(spy_call).value as result: # type: ignore[union-attr]
assert result == "hello world"
decoy.verify(spy_log.push(spy_call))
def test_handle_call_with_context_enter_none(
decoy: Decoy,
spy_log: SpyLog,
stub_store: StubStore,
subject: CallHandler,
) -> None:
"""It should allow a configured context value to be None."""
spy_call = SpyEvent(
spy=SpyInfo(id=42, name="spy_name", is_async=False),
payload=SpyCall(args=(), kwargs={}),
)
behavior = StubBehavior(context_value=None)
decoy.when(stub_store.get_by_call(spy_call)).then_return(behavior)
with subject.handle(spy_call).value as result: # type: ignore[union-attr]
assert result is None
decoy.verify(spy_log.push(spy_call))