title: Python SQLAlchemy - Mocking a model attribute's "desc" method
body: <p>In my application, there is a class for each model that holds commonly used queries (I guess it's somewhat of a "Repository" in DDD language). Each of these classes is passed the SQLAlchemy session object to create queries with upon construction. I'm having a little difficulty in figuring the best way to assert certain queries are being run in my unit tests. Using the ubiquitous blog example, let's say I have a "Post" model with columns and attributes "date" and "content". I also have a "PostRepository" with the method "find_latest" that is supposed to query for all posts in descending order by "date". It looks something like:</p>
  
  <pre><code>from myapp.models import Post
  
  class PostRepository(object):
      def __init__(self, session):
          self._s = session
  
      def find_latest(self):
          return self._s.query(Post).order_by(Post.date.desc())
  </code></pre>
  
  <p>I'm having trouble mocking the Post.date.desc() call. Right now I'm monkey patching a mock in for Post.date.desc in my unit test, but I feel that there is likely a better approach.</p>
  
  <p>Edit: I'm using mox for mock objects, my current unit test looks something like:</p>
  
  <pre><code>import unittest
  import mox
  
  class TestPostRepository(unittest.TestCase):
  
      def setUp(self):
          self._mox = mox.Mox()
  
      def _create_session_mock(self):
          from sqlalchemy.orm.session import Session
          return self._mox.CreateMock(Session)
  
      def _create_query_mock(self):
          from sqlalchemy.orm.query import Query
          return self._mox.CreateMock(Query)
  
      def _create_desc_mock(self):
          from myapp.models import Post
          return self._mox.CreateMock(Post.date.desc)
  
      def test_find_latest(self):
          from myapp.models.repositories import PostRepository
          from myapp.models import Post
  
          expected_result = 'test'
  
          session_mock = self._create_session_mock()
          query_mock = self._create_query_mock()
          desc_mock = self._create_desc_mock()
  
          # Monkey patch
          tmp = Post.date.desc
          Post.date.desc = desc_mock
  
          session_mock.query(Post).AndReturn(query_mock)
          query_mock.order_by(Post.date.desc().AndReturn('test')).AndReturn(query_mock)
          query_mock.offset(0).AndReturn(query_mock)
          query_mock.limit(10).AndReturn(expected_result)
  
          self._mox.ReplayAll()
          r = PostRepository(session_mock)
  
          result = r.find_latest()
          self._mox.VerifyAll()
  
          self.assertEquals(expected_result, result)
  
          Post.date.desc = tmp
  </code></pre>
  
  <p>This does work, though feels ugly and I'm not sure why it fails without the "AndReturn('test')" piece of "Post.date.desc().AndReturn('test')"</p>