1

I am trying to mock my sqlalchemy class using the unittest.mock module. I am specifying a return value, but when my test runs the query function that's been mocked, it returns a Nonetype variable instead.

Here is my test.

def TestLoginSuccessful(self):
    with mock.patch('CaseLoader_Fl.models.ndems.User') as mocksql:
        mocksql.query.filter_by('').first.return_value = ('test_user','test_password')
        is_validated = login_controller.validate_user('test_user','test_password')
    self.assertTrue(is_validated)

Here is the function I am testing, print(user) prints 'None'.

def validate_user(username,password):
    user = User.query.filter_by(username=username).first()
    print(user)
    if user:
        if user.check_password(password):
            return login_user(user)
        else:
            print('wrong pass')
            return False
    else:
        print('no user')
        return False

And here is my User class that inherits from SQLAlchemy.

class User(export_db.Model):
    __bind_key__ = 'ndems'
    username = export_db.Column(export_db.String(80), primary_key=True, unique=True)
    password = export_db.Column(export_db.String(80))
    admin = export_db.Column(export_db.Boolean())

    def __init__(self, username, password, admin):
        self.username = username
        self.password = self.set_password(password)
        self.admin = admin

    def __repr__(self):
        return '<User %r>' % self.username

    def set_password(self, password):
        return generate_password_hash(password)

    def check_password(self, password):
        return check_password_hash(self.password, password)

    def is_authenticated(self):
        return True

    def is_active(self):
        return True

    def is_anonymous(self):
        return False

    def get_id(self):
        return str(self.username)

Any help, or advice is appreciated.

Michael
  • 835
  • 2
  • 10
  • 24
  • You are patching the wrong reference to `User`. Patch it in the module under test, not the location where it was originally declared; the `from CaseLoader_Fl.models.ndems import User` statement you didn't show made it a global reference in the module where `validate_user` is defined. – Martijn Pieters Oct 16 '17 at 18:03
  • Ah, yes. I see the error of my ways. I replaced this line `with mock.patch('CaseLoader_Fl.models.ndems.User') as mocksql:` with this `with mock.patch('CaseLoader_Fl.controllers.login_controller.User') as mocksql:` and now the query is returning the mocked value correctly. I'm still very new to using the unittest.mock module, and I am clearly still learning. Thank you very much. – Michael Oct 16 '17 at 18:18

0 Answers0