Может ли Python's MiniMock создать макет функций, определенных в том же файле? - PullRequest
3 голосов
/ 23 сентября 2009

Я использую библиотеку Python MiniMock для модульного тестирования. Я хотел бы макетировать функцию, определенную в том же файле Python, что и мой doctest. Может ли MiniMock справиться с этим? Наивный подход терпит неудачу:

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()

Вот что произойдет, если я попытаюсь запустить этот код:

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

Редактировать: В соответствии с ответами ниже, это было определено как ошибка, и было исправлено в MiniMock .

Ответы [ 2 ]

5 голосов
/ 25 сентября 2009

Я только что ответил в списке рассылки исправлением MiniMock, которое исправляет это.

Пока оно не применено, вместо следующих двух строк в фрагменте его приложения:

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

вы также можетеиспользуйте

>>> mock('foo', nsdicts=(bar.func_globals,), returns=5)
1 голос
/ 23 сентября 2009

Это работает:

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()

Кажется, что foo in bar уже привязан к исходной функции к тому времени, когда происходит насмешка.

Это происходит потому, что при запуске doctests модуль doctest запускается в контексте копии глобального пространства имен модуля , но глобалы bar остаются оригинальными самостоятельно. Таким образом, функция mock изменяет foo, который находится в скопированном пространстве имен, но bar все еще смотрит на оригинал.

Я не знаю, есть ли лучший способ сделать это.

РЕДАКТИРОВАТЬ 2 : Я забрал его MiniMock был специально разработан для использования в докутах. Я подозреваю, что вы нашли ошибку.

РЕДАКТИРОВАТЬ : Думаю, рекомендуемый способ сделать это - настроить насмешку перед началом испытаний, например:

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()

Таким образом, сообщение «Called foo ()» также отсутствует в doctest.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...