I am currently writing a unit test for the following get_can_edit function in my serializer:
def get_can_edit(self, obj): request = self.context.get('request') user = User.objects.get(username=request.user) return user == obj.admin In my test, I call the function here:
def test_get_can_edit(self): self.request1 = RequestFactory().post('./fake_path') self.request1.user = SimpleLazyObject(self.user1) self.request1.query_params = {} self.serializer1 = ConferenceSerializer(context={'request': self.request1}) self.canEdit1 = self.serializer1.get_can_edit(self.conference) When I run the test, it fails the the error: 'User' object is not callable, and references the following line in the serializer get_can_edit function:
user = User.objects.get(username=request.user) However, when running in browser, the get_can_edit function performs correctly and has no problem with the 'User' objet being callable.
I originally assumed that there was a problem with the format of the fake data I was creating (I'm using factory_boy and RequestFactory to create the fake data). Using a debugger, I went into the get_can_edit function both by calling the test, and through the server by making a real request. In both cases, request.user and obj.admin were in the correct form, so I ruled out a data formatting error.
Next, I tried
User.objects.get(username=request.user) in the debuggers. It worked for the real request in the server, and returned the same 'User' object is not callable error for the fake request in the test. I did a quick stack overflow/google search for object is not callable errors in Django, but it looked like other cases were solved by making sure a model was imported correctly (mine is definitely imported correctly).
So at this point I know that there's a problem with my test case that does not exist with the real request, but I can't really figure out what it is, and I'm running out of ideas.
Full code:
Thanks so much, let me know if there's an easier way to go about this.
UPDATE: So I went back in the two different debuggers and did User.objects.all(). The one in the server with the real request returned the correct list of users. The one in the test with the fake request just returned anonymoususer. Because I'm using factory_boy to create my fake users, django can't find it in User.objects.
I've been told not to make real requests in my unit tests, so creating an actual user is out of the question.
I also tried changing the get_can_edit function to not check User.objects.. request.user is a SimpleLazyObject containing the user. What I tried doing was request.user.id and comparing it to obj.admin.id, but apparently when you do pretty much anything to a SimpleLazyObject, it consults User.objects to get to the actual User associated with it, so it still had the same error 'User' object is not callable.
So the bottom line is this: I need to add a fake user to User.objects without making a real request
app.models.Useranddjango.contrib.auth.model.User. Whats the reason for that? Can you also post the relevant models?