I am in fact
creating MockDS class with custom ldapadd,
actually I agree with Jan about how the
mocking process works:
1- reuse/create an ldap mocking class;
2- rewire existing tests on the mock;
Hence, a unit test.
Ok, I agree to add unit-testing. Just I
don't want to move integration tests
(the one against a real instance) in another repo.
I'd leave the integration tests there so that whenever somebody clones he can
test if the lib works for his installation.
It will *not* verify the correctness of ldapadd method of real
class (that is the job of ldapadd`s unit test
About testing ldapadd & co, we
should consider that - as of now - lib389 wraps
some python-ldap methods with *args, **kwds.
We should even be more consistent in parameter names between wrapping and
wrapped method .
On Tuesday 29 October 2013 14:18:59 Jan Rusnacko wrote:
I am not rewriting ldapadd,... methods of "real" DS class, I am in fact
creating MockDS class with custom ldapadd,... methods, _just_ like you
Furthermore, you can view it as a subclass of "real_ds" - even though it is
not a proper Python subclass, it inherits all functions from repl module
just like "real_ds" would (again through ModuleProxy mechanism). So,
methods that are defined in repl are the same for "real_ds" class and for
MockDS class, but ldap.. methods are different. So, basically exactly what
you suggest :)
Code of the whole class along with all methods is in file
tests/test_dsmodules/conftest.py line 7.
On 10/28/2013 12:02 PM, thierry bordaz wrote:
> Hi Jan,
> That is very impressive POC, far above my skill in python. Thanks for
> sharing this.
> I have a novice question.
> This implementation overwrites the basic ldapadd,ldapsearch...
> function of
> the "real" DS.
> An other approach is to write a 'mock_ds' class being a subclass of
> 'real_ds' and to overwrite the ldapadd,ldapsearch in mock_ds class (to
> store data into a dict). What would be the advantages of your
> approach ?>
> best regards
> On 10/25/2013 09:36 PM, Jan Rusnacko wrote:
>> Hello Roberto and Thierry,
>> as I promised, I am sending you a proof-of-concept code that
>> demonstrates, how we can mock DS in unit tests for library function (see
>> attachment). You can run tests just by executing py.test in tests
>> Only 3 files are of interest here:
>> lib389/dsmodules/repl.py - this is a Python module with functions - they
>> expect DS instance as the first argument. Since they are functions, not
>> methods, I can just mock DS and pass that fake one as the first argument
>> to them in unit tests.
>> tests/test_dsmodules/conftest.py - this file contains definition of mock
>> class along with py.test fixture, that returns it.
>> tests/test_dsmodules/test_repl.py - this contains unit tests for
>> functions from repl.py.
>> What I do is quite simple - I override ldapadd, ldapdelete .. methods of
>> mock DS class, so that instead of sending command to real DS instance,
>> they just store the data in 'dit' dictionary (which represents content
>> stored in DS). This way, I can check that when I call e.g. function
>> enable_changelog(..), in the end DS will have correct changelog entry.
>> To put it very bluntly - enable_changelog(..) function just adds correct
>> changelog entry to whatever is passed to it as the first argument. In
>> tests, it is mock DS, otherwise it would be real DS class that sends real
>> ldap commands to real DS instance behind.
>> Now I can successfully test that enable_changelog really works, without
>> going into trouble defining DSInstance or ldap calls at all. Also, I
>> believe this approach would work for 95% of all functions in lib389.
>> Another benefit is that unit tests are much faster, than on real DS
>> Sidenote: even though everything is defined in separate namespace of
>> module as function, in runtime they can be used as normal methods of
>> DSInstance. That is handled by DSModuleProxy. We already went through
>> this, but not with Roberto.
>> Hopefully, now with some code in our hands, we will be able to understand
>> each other on this 'mocking' issue and come to conclusions more
>> Let me know what you think.
>> Thank you,
Babel S.r.l. - http://www.babel.it
T: +39.06.9826.9651 M: +39.340.652.2736 F: +39.06.9826.9680
P.zza S.Benedetto da Norcia, 33 - 00040 Pomezia (Roma)
CONFIDENZIALE: Questo messaggio ed i suoi allegati sono di carattere
confidenziale per i destinatari in indirizzo.
E' vietato l'inoltro non autorizzato a destinatari diversi da quelli indicati
nel messaggio originale.
Se ricevuto per errore, l'uso del contenuto e' proibito; si prega di
comunicarlo al mittente e cancellarlo immediatamente.