-1

I try to test friend route for my flask application, but got the error:

AttributeError: 'NoneType' object has no attribute 'data'

I could test the model but when I want to test flask ('You are now Friend with ') I get the error above.

I am not expert in flask testing.

Can you tell me what is wrong and how can I fix it?

view.py:

@layout.route('/friend/<name>')
@login_required
def friend(name):
        user = Users.query.filter_by(name = name).first()
        if user == g.user:
            flash('You can\'t Friend yourself!')
            return redirect(url_for('layout.user',page=1,sortby='normal'))
        u = g.user.be_friend(user)
        if u is None:
            flash('You have been Friend with ' + name + '.')
            return redirect(url_for('layout.user',page=1,sortby='normal'))
       db.session.add(u)
       db.session.commit()
       flash('You are now Friend with ' + name + '!')
       return redirect(url_for('layout.user', page=1,sortby='normal'))

test.py:

 def test_friend(self):
        u1 = Users(name='monk1', email='monk1@example.com', age=25)
        u2 = Users(name='monk2', email='monk2@example.com', age=27)
        db.session.add(u1)
        db.session.add(u2)
        db.session.commit()
        response = self.assertTrue(u1.be_friend(u2))
        self.assertTrue('You have been Friend with monk2', response.data)
# I got error Here if I comment this line the test whole model.py works well But Now I want to test flash too that I get the mentioned error
LiLi
  • 301
  • 2
  • 7
  • 21

2 Answers2

3

When you do

self.assertTrue('You have been Friend with monk2', response.data)

the value of response in the previous step has been set to None, as the result of response = self.assertTrue(u1.be_friend(u2)) is None. The assertTrue would raise an error if the condition was not met, and so nothing is returned as its output, and hence the value of response is None.

Since None doesn't have any attribute named data, the error is thrown.

Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
0

Your problem is in the be_friend method:

def be_friend(self, user): #follow
    if not self.are_friends(user):
        self.is_friend.append(user)
        user.is_friend.append(self)
        return self

Here, if both users are already friends, you return nothing (hence Python automatically returns None). You can possibly fix it by changing your method to:

def be_friend(self, user): #follow
    if not self.are_friends(user):
        self.is_friend.append(user)
        user.is_friend.append(self)
    return self

Also, using assertIsNotNone instead of assertTrue would help you catch this bug.

You also cannot assign the return value as an HTTP response object since you are calling your method directly, not your view. You may rewrite your test as follows:

self.assertIsNotNone(u1.be_friend(u2))
self.assertTrue(u1.are_friends(u2))
Selcuk
  • 57,004
  • 12
  • 102
  • 110
  • Same error ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/peg/flask-Alembic/test/test_app.py", line 82, in test_friend self.assertTrue('You have been Friend with monk2', response.data) AttributeError: 'NoneType' object has no attribute 'data' @Selcuk – LiLi Feb 26 '15 at 13:47
  • Ok, are you trying to get the HTTP response in your test? It is not how unittest works. You are calling the method directly, not your view. See my updated answer. – Selcuk Feb 26 '15 at 13:55
  • thanx Now I get this errorAssertionError: False is not true @Selcuk :( – LiLi Feb 26 '15 at 14:18
  • Then your tests are running good. Either `be_friend` or `are_friends` method is broken. – Selcuk Feb 26 '15 at 14:27
  • But shouldn't the coverage increase or at leadt shows the this test is ok instead of errorAssertionError: False is not true ?? @Selcuk – LiLi Feb 26 '15 at 14:31
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/71786/discussion-between-lili-and-selcuk). – LiLi Feb 26 '15 at 14:32