我在跟踪this tutorial。
当我运行test_views.py
时,出现了一个错误,根据作者的说法,这个错误不应该出现:TypeError: quote_from_bytes() expected bytes
.
我的views
和我的test_views
和书中的一样,但是我用的是django 2.0.6而不是django 1.11,所以我的url.py
改变了,所以可能有问题。
编辑:
再看一下,问题似乎出在mock()
函数中。
当我使用patch('lists.views.List')
时,视图中的Print(list_)
给出<MagicMock name='List()' id='79765800'>
而不是List object (1)
/编辑
我的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'),
#]
我的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})
我的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)
我的完整回溯:
类型错误:quote_from_bytes()需要字节
能是什么?
谢谢你
2条答案
按热度按时间bfhwhh0e1#
最后我在网上找到了解决办法。
Django 2在某些地方不再支持字节串,所以当视图重定向mock Class List时,它会作为一个mock对象重定向,并且
iri_to_uri
django函数会抛出一个错误。在Django 1. 11中,iri_to_uri
强制将iri改为字节return quote(force_bytes(iri), safe="/#%[]=:;$&()+,!?*@'~")
,而现在是return quote(iri, safe="/#%[]=:;$&()+,!?*@'~")
。所以解决方案是在lists.views.py
中使用return redirect(str(list_.get_absolute_url()))
而不是return redirect(list_)
我希望这对其他人有帮助
fdbelqdn2#
我已经在测试代码中解决了这个问题,而没有更改所需的生产代码,如下所示:
请注意,赋值
some_method.return_value
会设置some_method
的响应,而不调用some_method()
,因此我们还可以测试该方法是否只被调用了一次。我喜欢这个解决方案的原因是它产生了所需的生产代码:
..,而不是在生产代码中使用类似
return redirect(str(list_.get_absolute_url()))
的变通方法,这是不可取的,因为它:1.不是所需的生产代码
1.是不太雅的生产代码
1.只返回模拟对象的名称作为字符串(即
<MagicMock name='NewListForm().save().get_absolute_url()' id='4363470544'>
),这不是我们想要的:我们希望调用get_absolute_url()
方法,该方法(不是str()
)应返回一个字符串形式的URL。