2014-09-15 3 views
18

Мне нужно создать какой-то MockMixin для моих тестов. Он должен включать в себя mocks для всего, что вызывает внешние источники. Например, каждый раз, когда я сохраняю модель в панели администратора, я вызываю несколько удаленных URL-адресов. Было бы хорошо, чтобы иметь, что издевались и использовать так:Тесты Django - объект патча во всех тестах

class ExampleTestCase(MockedTestCase): 
    # tests 

Таким образом, каждый раз, когда я сохранить модель в администратора, например, в функциональных тестах, это насмешка применяется вместо вызова удаленных URL-адресов.

Возможно ли это? Я могу сделать это для одного конкретного теста, это не проблема. Но было бы более полезно иметь какой-то глобальный макет, потому что я использую его много.

ответ

28

Согласно mock documentation:

патч может быть использован в качестве класса TestCase декоратора. Он работает , украшая каждый метод тестирования в классе. Это уменьшает код шаблона , когда ваши методы тестирования имеют общий набор исправлений.

В основном это означает, что вы можете создать базовый тестовый класс с @patch декоратора нанесенным на него, что бы издеваться ваши внешние вызовы, в то время как каждый метод испытания внутри будет выполняться.

Кроме того, вы можете использовать start() and stop() методы Patcher в в setUp() и tearDown() методы соответственно:

class BaseTestCase(TestCase): 
    def setUp(self): 
     self.patcher = patch('mymodule.foo') 
     self.mock_foo = self.patcher.start() 

    def tearDown(self): 
     self.patcher.stop() 
+2

И это также означает, что я должен украсить каждый из своих тестовых примеров, а не '' '' Mixin'''. Также неудобно, что я должен добавить дополнительный параметр для каждого метода тестирования. Но это лучше, чем ничего. – tunarob

+0

@ galozek см. Соответствующие темы: [здесь] (http://stackoverflow.com/questions/12219967/how-to-mock-a-base-class-with-python-mock-library) и [здесь] (http://stackoverflow.com/questions/11194847/how-do-i-directly-mock-a-superclass-with-python-mock). – alecxe

+0

@galozek Я также добавил еще один вариант - посмотрим, поможет ли он. Благодарю. – alecxe

13

Просто, чтобы добавить к ответу alecxe, в если вы используете teardown, то в соответствии с Документами

вам должен убедиться, что исправление «отменено», вызвав стоп

Итак, если в ваших тестах возникает исключение, исправление не будет отменено. Лучшим способом было бы позвонить addCleanup внутри вашего setUp. Тогда вы можете вообще опустить метод tearDown.

class BaseTestCase(TestCase): 
    def setUp(self): 
     self.patcher = patch('mymodule.foo') 
     self.mock_foo = self.patcher.start() 
     self.addCleanup(self.patcher.stop) # add this line 
+1

'tearDown' всегда будет вызываться, даже если ваши тесты вызывают исключение. – Dan

+2

Из документов: «Если setUp() терпит неудачу, что означает, что tearDown() не вызывается, тогда все функции очистки будут добавлены». Так что еще лучше назвать 'addCleanup', чем надеяться, что в' setUp' не возникают исключения. – Meistro

Смежные вопросы