Faking subscriptable objects

Create issue
Issue #22 new
Viktor Miroshnikov 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(
    s = self.instance.request_handler

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


    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:

        def test_create_server_side_session(self, mockSession):
            proxy = {}
            self.assertEqual(proxy['social.connect.context'], ...)
  2. Viktor Miroshnikov reporter

    mock.MagicMock would be right example of what we need to solve this kind of problems ;)

  3. 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.

  4. Viktor Miroshnikov 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?

  5. 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.

  6. Log in to comment