list_.save()
[...]
File "/workspace/superlists/lists/tests/test_views.py", line 84, in
check_owner_assigned
self.assertEqual(mock_list.owner, request.user)
AttributeError: 'List' object has no attribute 'owner'
Notice how the failure happens when we try and save, and then go inside our
side_ef
fect
function.
We can get it passing again like this:
lists/views.py.
if
form
.
is_valid
():
list_
=
List
()
list_
.
owner
=
request
.
user
list_
.
save
()
form
.
save
(
for_list
=
list_
)
return
redirect
(
list_
)
…
OK
But, boy, that’s getting to be an ugly test!
Listen to Your Tests: Ugly Tests Signal a Need to Refactor
Whenever you find yourself having to write a test like this, and you’re finding it hard
work, it’s likely that your tests are trying to tell you something. Nine lines of setup (three
lines for the mock user, four more lines for the request object, and three for our side-
effect function) is way too many.
What this test is trying to tell us is that our view is doing too much work, dealing with
creating a form, creating a new list object
and
deciding whether or not to save an owner
for the list.
We’ve already seen that we can make our views simpler and easier to understand by
pushing some of the work down to a form class. Why does the view need to create the
list object? Perhaps our
ItemForm.save
could do that? And why does the view need to
make decisions about whether or not to save the
request.user
? Again, the form could
do that.
While we’re giving this form more responsibilities, it feels like it should probably get a
new name too. We could call
NewListForm
instead, since that’s a better representation
of what it does… something like this?
lists/views.py.
# don't enter this code yet, we're only imagining it.
def
new_list
(
request
):
Listen to Your Tests: Ugly Tests Signal a Need to Refactor
|
341