2

I'm trying to test POSTing data to a view in django-rest-framework that requires authentication. But I can't. I've read many threads of supposed solutions, but can't find any that solves to me.

Serializer:

class ResearcherSerializer(serializers.ModelSerializer):
    studies = serializers.PrimaryKeyRelatedField(
        many=True, queryset=Study.objects.all()
    )

    class Meta:
        model = Researcher
        fields = ('id', 'first_name', 'surname', 'email', 'studies')

View:

class ResearcherSerializer(serializers.ModelSerializer):
    studies = serializers.PrimaryKeyRelatedField(
        many=True, queryset=Study.objects.all()
    )

    class Meta:
        model = Researcher
        fields = ('id', 'first_name', 'surname', 'email', 'studies')

Test:

class ResearcherAPITest(APITestCase):
    base_url = reverse('api_researchers')
# ...

def test_POSTing_a_new_researcher(self):
    user = User.objects.create(username='lab1', password='nep-lab1')
    self.client.login(username=user.username, password=user.password)
    response = self.client.post(
        self.base_url,
        {
            'first_name': 'João',
            'surname': 'das Rosas',
        }
    )
    self.assertEqual(response.status_code, status.HTTP_201_CREATED)
    new_researcher = Researcher.objects.first()
    self.assertEqual(new_researcher.first_name, 'João')
    self.client.logout()

I receive this error:

FAIL: test_POSTing_a_new_researcher (experiments.tests.test_api.ResearcherAPITest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/caco/Workspace/nep-system/nep/experiments/tests/test_api.py", line 130, in test_POSTing_a_new_researcher
    self.assertEqual(response.status_code, status.HTTP_201_CREATED)
AssertionError: 403 != 201

----------------------------------------------------------------------

Had read drf Testing documentation but can't see what I'm doing wrong.

3 Answers 3

6

The right way to create a user is using User.objects.create_user() as teach official Django documentation. When using create_user() method the password parameter is hashed before saving in database, while common create() method does not do that.

Also, it's necessary login with

self.client.login(username=user.username, password='nep-lab1')

instead user.password as password parameter in APIClient.client.login() method, as pointed out by @oz-main.

Sign up to request clarification or add additional context in comments.

Comments

1

I don't think you can't access to user.password as you are trying to. Also, I'd give some advices:

  • Since you're using APITestCase. Try to use setUp method to create your user in database. That way you will be able to re-use that user in other cases
  • Follow pep8 guidelines to write your code.test_POSTing_a_new_researcher is a very weird method name
  • Take a look at factory boy, it might make your life easier by replacing the fixture approach

Good resource for testing: http://www.obeythetestinggoat.com/

1 Comment

Thanks for the tips man. I verified here and user.password is accessible. By the way, I'm learning Django TDD with obeythetestinggoat.com, a great resource. But there is a quick Appendix covering testing API and django-rest-framework in particular. No authentication tests. Anyhow thanks for help me.
1

base on the test case you've written the test user is not logged in because you are trying to log in a user using the hashed password and not the nep-lab1. you can test if you've successfully logged in by:

print self.client.login(username=user.username, password=`nep-lab1`)
# True if logged in and False if not

and since the user is not logged your test on posting a new researcher via api would result to FORBIDDEN(403) http response and not CREATED(201)

1 Comment

In fact, printing user.password gives 'nep-lab1'. I discovered here that the correct way of creating user is with User.objects.create_user() and not User.objects.create() like common model classes. The first method hashes the password for us. Anyhow thanks for replying. You've open my mind to that error.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.