I'm following this tutorial.
When I run test_views.py
I have an error that shouldn't be there according the author: TypeError: quote_from_bytes() expected bytes
.
My views
and my test_views
are the same like the book, but I'm using django 2.0.6 instead django 1.11 so my url.py
change, so maybe here's the problem.
Edit:
at a second look the problem appears to be in the mock()
function.
When I use patch('lists.views.List')
the Print(list_)
in my view gives <MagicMock name='List()' id='79765800'>
instead of List object (1)
/edit
My lists/urls.py
:
urlpatterns = [
path('new', views.new_list, name='new_list'),
path('<slug:list_id>/',
views.view_list, name='view_list'),
path('users/<email>/', # I'm not sure about this one but it works in other tests
views.my_lists, name='my_lists'),
]
#instead of:
#urlpatterns = [
# url(r'^new$', views.new_list, name='new_list'),
# url(r'^(\d+)/$', views.view_list, name='view_list'),
# url(r'^users/(.+)/$', views.my_lists, name='my_lists'),
#]
My lists/views.py
:
[...]
def new_list(request):
form = ItemForm(data=request.POST)
if form.is_valid():
list_ = List()
list_.owner = request.user
list_.save()
form.save(for_list=list_)
Print(list_)
return redirect(list_)
else:
return render(request, 'home.html', {"form": form})
My lists/tests/test_views.py
:
@patch('lists.views.List')
@patch('lists.views.ItemForm')
def test_list_owner_is_saved_if_user_is_authenticated(self,
mockItemFormClass, mockListClass
):
user = User.objects.create(email='a@b.com')
self.client.force_login(user)
self.client.post('/lists/new', data={'text': 'new item'})
mock_list = mockListClass.return_value
self.assertEqual(mock_list.owner, user)
My full traceback:
What can be?
thank you
At last I found the solution on-line.
Django 2 doesn't support anymore bytestrings in some places so when the views redirect the mock Class List it does as a mock object and the
iri_to_uri
django function throws an error. In django 1.11iri_to_uri
forced the iri to a bytesreturn quote(force_bytes(iri), safe="/#%[]=:;$&()+,!?*@'~")
instead now isreturn quote(iri, safe="/#%[]=:;$&()+,!?*@'~")
. So the solution is toreturn redirect(str(list_.get_absolute_url()))
instead ofreturn redirect(list_)
in thelists.views.py
I hope this helps someone else