2009-09-22 5 views
3

J'utilise la bibliothèque Python MiniMock pour les tests unitaires. Je voudrais simuler une fonction définie dans le même fichier Python que mon doctest. MiniMock peut-il gérer cela? L'approche naïve échoue:Le MiniMock de Python peut-il créer une simulation de fonctions définies dans le même fichier?

def foo(): 
    raise ValueError, "Don't call me during testing!" 

def bar(): 
    """ 
    Returns twice the value of foo() 

    >>> from minimock import mock 
    >>> mock('foo',returns=5) 
    >>> bar() 
    Called foo() 
    10 

    """ 
    return foo() * 2 

if __name__ == "__main__": 
    import doctest 
    doctest.testmod() 

est ici ce qui se passe si je tente d'exécuter ce code:

********************************************************************** 
File "test.py", line 9, in __main__.bar 
Failed example: 
    bar() 
Exception raised: 
    Traceback (most recent call last): 
     File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/doctest.py", line 1212, in __run 
     compileflags, 1) in test.globs 
     File "<doctest __main__.bar[2]>", line 1, in <module> 
     bar() 
     File "test.py", line 13, in bar 
     return foo() * 2 
     File "test.py", line 2, in foo 
     raise ValueError, "Don't call me!" 
    ValueError: Don't call me! 
********************************************************************** 
1 items had failures: 
    1 of 3 in __main__.bar 
***Test Failed*** 1 failures. 

Edit: Selon les réponses ci-dessous, ce qui a été identifié comme un bug, et a été fixed in MiniMock.

Répondre

5

Je viens de répondre sur la liste de diffusion avec un correctif MiniMock qui résout ce problème.

Jusqu'à ce qui est appliqué, au lieu des deux lignes suivantes dans l'extrait de itsadok:

>>> mock('foo',returns=5) 
>>> bar.func_globals['foo'] = foo 

vous pouvez également utiliser

>>> mock('foo', nsdicts=(bar.func_globals,), returns=5) 
+0

J'ai appliqué le correctif pour donner un pourboire (voir http://bitbucket.org/jab/minimock/changeset/bb9528bb454d/) . – user161642

1

Cela fonctionne:

def foo(): 
    raise ValueError, "Don't call me during testing!" 

def bar(): 
    """ 
    Returns twice the value of foo() 

    >>> from minimock import mock 
    >>> mock('foo',returns=5) 
    >>> bar.func_globals['foo'] = foo 
    >>> bar() 
    Called foo() 
    10 

    """ 
    return foo() * 2 

if __name__ == "__main__": 
    import doctest 
    doctest.testmod() 

Il semble que le foo dans le bar est déjà lié à la fonction originale au moment où le moqueur a lieu. Cela se produit parce que lors de l'exécution des doctests, le module doctest runs in the context of a copy of the module's global name space, mais les globals bar restent leur original. Donc, la fonction mock modifie le foo qui se trouve dans l'espace de noms copié, mais bar regarde toujours l'original.

Je ne sais pas s'il existe une meilleure façon de procéder.

EDIT 2: Je le reprends. MiniMock a été spécialement conçu pour être utilisé dans les doctests. Je soupçonne que tu as trouvé un bug.

EDIT: Je suppose que la méthode recommandée pour le faire est de mettre en place les moqueries avant de commencer les essais, comme ceci:

def foo(): 
    raise ValueError, "Don't call me during testing!" 

def bar(): 
    """ 
    Returns twice the value of foo() 

    >>> bar() 
    10 

    """ 
    return foo() * 2 

if __name__ == "__main__": 
    from minimock import mock 
    mock('foo',returns=5) 
    import doctest 
    doctest.testmod() 

De cette façon, le message « foo() » est également pas dans le doctest.

+0

Ce problème a été élevé dans la liste de diffusion MiniMock: http://groups.google.com/group/minimock-dev/browse_thread/thread/f8a583bc862f279?hl=fr –

Questions connexes