测试视图集中的详细动作

时间:2018-07-30 07:23:57

标签: python django unit-testing django-rest-framework

我写了一个Viewset,它带有一组身份验证,权限和序列化程序,现在想对其进行单元测试。 问题在于,从测试中执行UserViewSet.as_view(actions={'get': 'retrieve'})时,viewset派发方法未设置self.detail = True

class UserViewSet(viewsets.ModelViewSet):
    serializer_class = UserSerializer
    lookup_field = 'pk'
    authentication_classes = (FirebaseAuthentication,)
    permission_classes = (IsFirebaseVerified, IsAuthenticatedOrReadOnly)
    queryset = User.objects.all()

    def get_serializer_class(self):
        '''
        if a user queries his own details, or signs up, return his private info
        '''
        # BUG: self.detail is undefined
        if (self.detail and self.request.user.pk == self.kwargs.get('pk'))\
                or self.action == 'create':
            return PrivateUserSerializer
        return UserSerializer

相关测试:

def generate_fake_user_data(pk, name):
    return {
        'pk': pk,
        'email': '{}@example.com'.format(name.lower()),
        'password': 'password{}'.format(name),
    }


class UserViewSetTestCase(TestCase):
    @classmethod
    def setUpClass(cls):
        cls.users = MockSet(
            User(**generate_fake_user_data(1, 'A')),
            User(**generate_fake_user_data(2, 'B')),
            model=User,
        )
        cls.factory = APIRequestFactory()
        UserViewSet.queryset = cls.users

    @classmethod
    def tearDownClass(cls):
        UserViewSet.queryset = User.objects.all

    def test_authed_user_retrieves_himself(self):
        request = self.factory.get('/api/users/1/')
        force_authenticate(request, user=self.users.first())
        retrieve_view = UserViewSet.as_view(actions={'get': 'retrieve'})
        response = retrieve_view(request, pk=1)

        # BUG: response.data has been returned by UserSerializer
        # hence assert fails with email not found
        self.assertDictContainsSubset({
            'pk': 1,
            'full_name': 'John A',
            'email': 'a@example.com',
        }, response.data)
        self.assertFalse('password' in response.data)

self.detail设置为True时从测试中调用视图的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

嗯,看来我只需要将此参数赋予as_view

retrieve_view = UserViewSet.as_view(actions={'get': 'retrieve'},
                                            detail=True)