Code

Opened 13 months ago

Last modified 13 months ago

#20073 new New feature

Provide API for creating User objects in tests

Reported by: jacek.tomek@… Owned by: nobody
Component: contrib.auth Version: 1.5
Severity: Normal Keywords: 1.5 user tests
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Sometimes you want to create a user object for tests (e.g. create User, login, add some object and test if user info was stored within object; whatever).

Prior 1.5 it was rather easy task:

User._default_manager.create_user('admin', 'mail', 'admin')
user.is_staff = True  # make him admin
user.save()

However, since introducing interchangeable User models, it may fail (even when using User = get_user_model() first) because create_user or create_superuser may take different parameters.

I know there is skipIfCustomUser decorator, but what about tests that just need to check something with user?

There should be a mandatory method like create_test_user}} on {{{UserManager. Method should take no arguments and return usable User instance. There could also be create_test_superuser. With those methods unittesting with User colud be possible in almost all cases.

Attachments (0)

Change History (6)

comment:1 Changed 13 months ago by jacob

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted

I don't know that it's possible to create such an API; how do you know what some arbitrary user model requires? I suspect the best pattern here is to use override_settings() to make sure your tests run against a known user model. But either way we need to document that.

comment:2 Changed 13 months ago by jacek.tomek@…

It seems I wasn't clear.

You're right - only the creator of user model know, what it requires. So the point of this proposal is to encourage the creators to include such a methods in their user models (so that every user model can be blackbox tested). The presence of these methods can be checked by some validation on django startup.

To sum up: I would like to:

  • change docs to state that every custom user model must provide create_test_user method.
  • implement such a method on provided (in django.contrib.auth) user models
  • check presence of these methods in model validation (to force coders to implement them)

With this we would get a handy way of running tests with any user model.

comment:3 Changed 13 months ago by Jcatalan

You want this for instance for writing the tests for a pluggable app that can run with any User model? In that case maybe its not about having a way to create a User but about assuming a certain needed API for the User model and then mocking the user object in your tests.

Your code should fail if the User doesn't meet the requirements. And that wouldn't be a bug I think. Does that make sense?

comment:4 Changed 13 months ago by anonymous

Exactly, I want this for mocking User instances in tests for a pluggable app. Not for creating real Users.

The code wouldn't fail if every User model had the API described above. And I presented a way to force this.

comment:5 Changed 13 months ago by anonymous

As far as I understand, mocking and creating a User instance are 2 different things. For mocking you could just use sth like python mock library. You wouldn't need an actual User instance which is really what you are trying to avoid by mocking the object.

Am I being clear enough? By mocking the user you can avoid depending on any User class and just test against the expected API.

comment:6 Changed 13 months ago by jacek.tomek@…

Ok, I see. So I would like not to mock the user - in order to test if app really works in project with some custom user model.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as new
The owner will be changed from nobody to anonymous. Next status will be 'assigned'
as The resolution will be set. Next status will be 'closed'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.