Python unittest mock SQLAlchemy model property

Viewed 122

Following are my SQLAlchemy example models in Flask.

class Debtor(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Unicode)


class DebtorBranch(db.Model):
    ... omitted properties

    debtor = db.relationship("Debtor")
    debtor_id = db.Column(
        db.Integer, db.ForeignKey("debtors.id")
    )

And I created a test that will mock the DebtorBranch.debtor relational field.

@mock.patch(
    'services.debtor.models.DebtorBranch.debtor',
    new_callable=mock.PropertyMock
)
def test_debtor_branch_debtor(self, mock_debtor_property):

    mock_debtor_property.side_effect = [
        DebtorBranch.debtor,
        Debtor(name='external_debtor_name')
    ]

    external_debtor = get_debtor_from_external_registry()

    debtor_branch = self.session.query(DebtorBranch)
            .join(Debtor, DebtorBranch.debtor)
            .filter(Debtor.id == external_debtor.id)
            .first()

    assert debtor_branch.debtor.name == external_debtor.official_name

However, whenever I access the DebtorBranch.debtor in .join(Debtor, DebtorBranch.debtor).

It returns a MagicMock instance <MagicMock name='debtor()' id='281472612338208'> rather than the property itself leading to this error:

sqlalchemy.exc.InvalidRequestError: Don't know how to join to <class 'Debtor'>. Please use the .select_from() method to establish an explicit left side, as well as providing an explcit ON clause if not present already to help resolve the ambiguity.

Is there a possibility to return the DebtorBranch.debtor field from the side_effect even though it is the property to be mocked?

0 Answers
Related