it-swarm.com.ru

Любой реальный пример Word о том, как setUp () и tearDown () должны использоваться в PHPUnit?

Методы setUp() и tearDown() вызываются до и после каждого теста. Но на самом деле, есть ли реальный пример Word о том, зачем мне это нужно?

Осматривая чужие тесты, я всегда вижу что-то вроде:

public function setUp()
{
    $this->testsub = new TestSubject();
}

public function tearDown()
{
    unset($this->testsub);
}

public function testSomething()
{
    $this->assertSame('foo', $this->testsub->getFoo());
}

Конечно, между этим способом и «старым» способом локальной переменной практически нет различий.

25
gremo

Если вы выполняете каждый тестовый метод индивидуально, ваш тестовый код будет содержать много строк, которые просто создают объект для тестирования. Этот общий код может (но не ДОЛЖЕН) входить в метод настройки.

Все, что необходимо сделать для создания объекта, подлежащего тестированию, затем также переходит в метод настройки, например, создание фиктивных объектов, которые вводятся в конструктор объекта тестирования.

Ничего из этого не нужно отключать, потому что следующий вызов setup инициализирует переменные-члены класса новым набором объектов.

Единственное, что нужно разбирать, - это если ваш тест навсегда оставляет что-то позади, например, файлы, которые были созданы, или записи в базе данных. На самом деле не очень хорошая идея писать тесты, которые делают такие вещи, но в какой-то момент вы не можете больше абстрагироваться и должны касаться таких вещей, как жесткий диск, база данных или реальная сеть.

Таким образом, настройки гораздо больше, чем требуется для разборки, и я всегда удаляю метод разборки, если для этого теста не требуется никаких действий.

Что касается издевательств, я работаю так:

private $_mockedService;
private $_object;
protected function setUp()
{
    $this->_mockedService = $this->getMock('My_Service_Class');
    $this->_object = new Tested_Class($this->_mockService);
}

public function testStuff()
{
    $this->_mockedService->expects($this->any())->method('foo')->will($this->returnValue('bar'));
    $this->assertEquals('barbar', $this->_object->getStuffFromServiceAndDouble());
}
27
Sven

Вы можете создать экземпляр набора объектов фикстуры и сделать их доступными в качестве переменных экземпляра в каждом тесте, вместо того, чтобы создавать их индивидуально для каждого теста.

Вы можете создавать ресурсы, такие как дескриптор файла, в setUp, а затем убедитесь, что закрыли их в tearDown. Если вы пишете временные файлы, вы можете удалить их. Если вы открываете соединение с базой данных, вы можете закрыть его (хотя вы можете сделать это в другом месте - setupBeforeClass/tearDownAfterClass, который вызывается для каждого тестового файла, а не для каждого тестового случая.)

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

4
Koobz

Вы можете использовать это почти в любое время, когда у вас будет зависимость внутри класса, который вы тестируете. Классическим примером этого может быть какой-то объект, хранящий состояние приложения (объект сеанса, корзина и т.д.).

Скажем, например, у меня был класс, который собирался рассчитать стоимость доставки по содержимому корзины, определенной объектом корзины. И скажем, эта корзина покупок передается в класс расчета доставки с помощью внедрения зависимостей. Чтобы протестировать большинство методов класса, вам может потребоваться создать экземпляр объекта корзины и установить его в классе для модульного тестирования различных методов. Вам также может понадобиться добавить товары в корзину. Таким образом, вы могли бы иметь такую ​​настройку:

public function setUp()
{
    $this->cart = new cart();
    $this->cart->add_item('abc');
    $this->cart->add_item('xyz');
}

Предположим также, что ваши методы тестирования могут на самом деле изменить элементы корзины, украсив их информацией о стоимости доставки. Вам не нужна информация от одного пробного кровотечения до следующего, поэтому вы просто сбрасываете корзину в конце.

public function tearDown()
    unset($this->cart);
}
1
Mike Brant

В приведенном примере в принятом ответе есть утечка памяти . Вы должны добавить tearDown:

protected function tearDown()
{
    $this->_mockedService = null;
}

PHPUnit создает новый объект теста для каждого вызова метода теста. Так что, если есть 4 метода тестирования - будет 4 объекта и будет создано 4 mockedService. И они не будут удалены до конца скрипта (весь набор тестов) . Поэтому вам нужно удалить все объекты и сбросить все переменные в tearDown, чтобы предотвратить утечку памяти.

1
Nick