Testing return value of SQLAlchemy parent-child relationship query
<p>Say I have two models set up like so:</p>

<pre><code>class ParentFoo(SqlBase):
  __tablename__ = "parents"

  id = Column(String, primary_key=True)
  children = relationship("ChildFoo", backref="parents")

class ChildFoo(SqlBase):
  __tablename__ = "children"

  id = Column(String, primary_key=True)
</code></pre>

<p>Now in a request handler, say I want to get all children entities from the database given a parent:</p>

<pre><code>class RequestHandler():

  def get(self, parent_id):
    parent = database.query(parent_id)
    children = parent.children
    send_response(children)
</code></pre>

<p>The SQLAlchemy ORM API allows this type of query. The problem for me is when I'm writing my tests. I have a generic <code>RequestHandler</code> class that takes a <code>ParentFoo</code> and a <code>ChildFoo</code> class as arguments in the constructor. So my request handler class actually looks like this:</p>

<pre><code>class GenericRequestHandler():

  def __init__(self, parent_class, child_class):
    self.parent_class = parent_class
    self.child_class = child_class

  def get(self, parent_id):
    parent = database.query(self.parent_class, parent_id)
    children = parent.getattr(self.child_class.__tablename__, None)
</code></pre>

<p>As long as the column name on the parent matches the <code>__tablename__</code> for the child entities, this will work. I enforce this convention. The problem is testing this.</p>

<p>Python's <code>mock</code> library doesn't seem to provide for return values on attribute lookups and I don't want to mock out the <code>getattr</code> function, because it's used elsewhere in my get method.</p>

<p>Any thoughts?</p>

<p>Edit 1:
Regarding my comment about attribute lookups: I can mock out a function and provide a return value.</p>

<pre><code>mocked_function.return_value = my_desired_value
</code></pre>

<p>But how do I mock out an attribute?</p>

<pre><code>mocked_object.attribute_of_interest = my_desired_value
</code></pre>

<p>Edit 2:
In my tests, I provide <code>MagicMock</code> objects to the constructor for the parent and child classes, and I set a <code>MagicMock</code> object to be returned by the call to <code>database.query</code>:</p>

<pre><code>parent_class_mock = MagicMock()
child_class_mock = MagicMock()
parent_entity = MagicMock()
type(parent_entity).getattr = PropertyMock(return_value=[child_entity])
database.query.return_value = parent_entity

class ConcreteRequestHandler(GenericRequestHandler):
  def __init__(self, parent_class, child_class):
    super(ConcreteRequestHandler, self).__init__(parent_class, child_class)
</code></pre>

<p>As you can see, I tried to use <code>mock</code>'s <code>PropertyMock</code> to set an attribute. When I ran the test, I got an error saying <code>'list' object not callable</code>. Please see <a href="https://stackoverflow.com/questions/36781464/python-mock-return-of-a-getattr-call">this</a> SO question I asked related to this.</p>