Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #25257 > unrolled thread

Mocked object returning another Mocked object

Started byJean-Michel Pichavant <jeanmichel@sequans.com>
First post2012-07-13 12:09 +0200
Last post2012-07-13 12:37 +0200
Articles 2 — 2 participants

Back to article view | Back to comp.lang.python


Contents

  Mocked object returning another Mocked object Jean-Michel Pichavant <jeanmichel@sequans.com> - 2012-07-13 12:09 +0200
    Re: Mocked object returning another Mocked object Ulrich Eckhardt <ulrich.eckhardt@dominolaser.com> - 2012-07-13 12:37 +0200

#25257 — Mocked object returning another Mocked object

FromJean-Michel Pichavant <jeanmichel@sequans.com>
Date2012-07-13 12:09 +0200
SubjectMocked object returning another Mocked object
Message-ID<mailman.2074.1342174174.4697.python-list@python.org>
Greetings Fellow Group,


I'd need your help to fix some issues I have with my unitary tests.
I'm trying to bring them to the next level by Mocking equipments 
controlled by my application.

Despite me reading http://www.voidspace.org.uk/python/mock/index.html I 
cannot figure out how to do the following :

I have an App object with the 'target' attribute. This target is 
controlling a piece of hardware. The hardware itself holds a software, 
hence the target object having an 'api' attribute. I hope I make sense.

So basically I'd like

self.target.api.<anyMethod>()

to return a Mocked object (Mocking an Api object response).



** Question **

I do I make *all* method calls return a specifik Mock?

target = Mock()

result = target.api.start() # I'd like result to be a Mock I defined 
with the 'returnCode' attribute

print result.returnCode
1

But I would like to do it for any method of api (the list is huge, 
setting each of them is not an option I think) so that in the end,

result = target.api.start()
result = target.api.stop()
result = target.api.reset()
result = target.api.loadSw()

return all the same Mock object (with 'returnCode')


Any idea ?

Cheers,

JM

[toc] | [next] | [standalone]


#25258

FromUlrich Eckhardt <ulrich.eckhardt@dominolaser.com>
Date2012-07-13 12:37 +0200
Message-ID<sca5d9-cd6.ln1@satorlaser.homedns.org>
In reply to#25257
Am 13.07.2012 12:09, schrieb Jean-Michel Pichavant:
> I have an App object with the 'target' attribute. This target is
> controlling a piece of hardware. The hardware itself holds a software,
> hence the target object having an 'api' attribute. I hope I make sense.
>
> So basically I'd like
>
> self.target.api.<anyMethod>()
>
> to return a Mocked object (Mocking an Api object response).
>
> ** Question **
>
> I do I make *all* method calls return a specifik Mock?
>
> target = Mock()
>
> result = target.api.start()

I'm not sure where the "target" here comes in. As I understand it, the 
goal is to write the "api" object so that you can call any function on it...

> I'd like result to be a Mock I defined
> with the 'returnCode' attribute
>
> print result.returnCode
> 1

...and every function should just return the same return code. Right?


> But I would like to do it for any method of api (the list is huge,
> setting each of them is not an option I think) so that in the end,
>
> result = target.api.start()
> result = target.api.stop()
> result = target.api.reset()
> result = target.api.loadSw()
>
> return all the same Mock object (with 'returnCode')

There are two options I could think of:

1. Intercept attribute lookup

 From the top of my head, the syntax is something like this:

class TargetMock(object):
     def __getattr__(self, name):
         def default_result(*vargs, **kwargs):
             return ReturnCode(1)
         return default_result

This just ignores the name and returns a function returning the mock 
return code. I think you get the idea.


2. Intercept individual lookups

class TargetMock(object):
     def _default(self, *vargs, **kwargs):
         return ReturnCode(1)
     start = _default
     stop = _default
     reset = _default
     loadSW = _default

Yes, this ignores your claim that the list of functions is too big to 
add every function individually. I'd just add them on demand when a test 
accesses a function that isn't there yet. The advantage is that it shows 
clearly which of the functions are just stubs if you actually implement 
a few of them differently.


If the list functions is really that huge but you have a class (the real 
driver class) that defines this API, then you could extract this list 
programmatically. That way, you could also ensure that your mock API 
doesn't provide functions not supported by the original.


Good luck!

Uli

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web