Opened 6 years ago

Closed 3 years ago

#20073 closed New feature (wontfix)

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


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

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.

Change History (7)

comment:1 Changed 6 years ago by Jacob

Triage Stage: UnreviewedAccepted

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 6 years 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 6 years 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 6 years 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 6 years 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 6 years 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.

comment:7 Changed 3 years ago by Tim Graham

Resolution: wontfix
Status: newclosed

With the test discovery changes in 1.6, the idea of third-party apps shipping "integration tests" seems to be abandoned from what I can tell. For example, the skipIfCustomUser decorator is no longer used in Django itself and will be removed in Django 2.0 (#22993). Without an obvious use case for the proposed functionality or way to move this ticket forward, I think we should close it.

Note: See TracTickets for help on using tickets.
Back to Top