1. Kumar McMillan
  2. fudge
  3. Issues
Issue #22 new

Faking subscriptable objects

Victor M
created an issue

Is there any option/example how to fake subscriptable object? {{{

!python

def create_server_side_session(self, redirect_uri): s = self.request_handler # save context information session = Session(db=s.repo.redis) session["social.connect.context"] = dict( application=s.get_current_app(), redirect_uri=redirect_uri, user_id=s.get_current_user()) session.save() return session }}}

{{{

!python

@fudge.patch('backend.handlers.social.Session') def test_create_server_side_session(self, mockSession): redirect_uri = fudge.Fake() fake_app = fudge.Fake() fake_redirect_uri = fudge.Fake() fake_user_id = fudge.Fake()

    expect_dict = dict(
        application=fake_app,
        redirect_uri=fake_redirect_uri,
        user_id=fake_user_id
    )
    s = self.instance.request_handler
    s.expects('get_current_app').with_args().returns(fake_app)
    s.expects('get_current_user').with_args().returns(fake_user_id)

    faked_session = fudge.Fake('fakeSession')
    faked_session.expects('save').with_args()
     (faked_session
     .expects('__setitem__')
     .with_args("social.connect.context", expect_dict))


    (mockSession
     .expects_call()
     .with_args(db=s.repo.redis)
     .returns(faked_session))

    result = self.instance.create_server_side_session(redirect_uri)
    self.assertEquals(result, faked_session)

}}}

I'm getting: {{{

!python

TypeError: 'Fake' object does not support item assignment

}}}

Or {{{

!python

TypeError: 'Fake' object is not subscriptable

}}}

Probably I'll avoid that problem with faking init and save methods, but still have a question how to mock subscriptables :)

Comments (5)

  1. Kumar McMillan repo owner

    There isn't currently a way to mock dict like objects (it would be nice to add support for that). As a workaround, you could do this:

        @fudge.patch('backend.handlers.social.Session')
        def test_create_server_side_session(self, mockSession):
            proxy = {}
            mockSession.expects_call().returns(proxy)
            self.instance.create_server_side_session(redirect_uri)
            self.assertEqual(proxy['social.connect.context'], ...)
    
  2. Kumar McMillan repo owner

    Yep. I'm actually in the process of using mock within fudge for all the patching. Merging fudge.Fake with Mock probably isn't worth the effort though. I think this can be solved by simply defining setitem and getitem on fudge.Fake and hooking them up to declared calls the same way call and init do it.

  3. Victor M reporter

    I wish that would be so easy. But it doesnt work:

    $ python
    Python 2.7.1 (r271:86832, Jun 16 2011, 16:59:05) 
    [GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import fudge
    >>> f = fudge.Fake().provides('__setitem__').provides('__getitem__')
    >>> f['a']
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'Fake' object is not subscriptable
    >>> f['a']=1
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'Fake' object does not support item assignment
    >>> 
    

    So combining two mocking libraries is a good idea?

  4. Kumar McMillan repo owner

    Did you try the proxy strategy I mentioned? This works fine for me:

    In [1]: from fudge import Fake
    In [2]: proxy = {}
    In [5]: Session = Fake().is_callable().returns(proxy)
    In [6]: sess = Session()
    In [7]: sess['social.connect.context'] = {'foo': 1}
    In [8]: proxy
    Out[8]: {'social.connect.context': {'foo': 1}}
    

    btw, I use mock and fudge in the same test suite. It works fine.

  5. Log in to comment